Arc Forumnew | comments | leaders | submit | hjek's commentslogin

I actually like `#<void>`, because it makes more of a distinction between pure and impure functions.

I read a good blog post[0] recently on how not distinguishing makes it difficult to guess the behaviour of simple and short code snippets (in JavaScript, but the same could apply to Arc).

[0]: https://medium.com/@winwardo/the-principle-of-least-astonish...

reply

1 point by akkartik 28 days ago | link

There's definitely a tension between being a concise language and being a safe language. Arc doesn't try to help newcomers avoid simple mistakes. It gives them enough rope to hang themselves, like with unhygienic macros. That's partly why I stopped using Arc to teach my students programming (http://akkartik.name/post/mu).

reply

2 points by hjek 55 days ago | link | parent | on: Show Arc: Debate (very alpha)

Thanks for posting that. (The issue is not specific to Windows.)

I've switched from Notabug to Gitlab now, because Notabug is being painfully slow.

https://gitlab.com/hjek/undebatable/issues/1

reply

2 points by hjek 70 days ago | link | parent | on: Clojure Anaphoric Macros

If you include * whitespace * between words and stars, they are not parsed as an emphasized section.

-----

2 points by hjek 71 days ago | link | parent | on: Clojure Anaphoric Macros

Racket doesn't have anaphoric macros as part of the core language (although there is a module for that), so that's a bit difficult getting used to when coming from Arc, but I find that pattern matching[0] can be used to the same effect:

    (match 123
       ((and (? even?) it) (~a it " is even"))
       (it (~a it " is odd")))
[0]: https://docs.racket-lang.org/reference/match.html

-----

3 points by hjek 84 days ago | link | parent | on: Show Arc: Debate (very alpha)

> I've only had to time to take quick look, but I'm impressed at how clean the code looks.

Good to know that it's somewhat readable for people who are not me!

> I could be wrong, but it actually looks smaller in size than Arc's version, but with more features.

It's still smaller and it does have file upload, but there's a lot of news.arc features missing before this one is usable.

> > not a general purpose cms (link to 'The CMS Trap')

> That's me. I'm that guy - lol (well not quite but close).

I read a blog post[0] about Wagtail, a Python CMS, and wanted to try it out. Once up and running, it has a user login/registration form, but you literally can't post anything, because it's more like a CMS framework or something (or maybe that is what CMS really means?). To me that embodied 'The CMS trap'.

> Between, no JS, Free Software and the above I'm getting that you and I have very different goals :)

Yea, good to hear different opinions here.

Ok, so I'm not totally against JS, and I'm using it myself for other stuff. I think I'm just really pro progressive enhancement, and it's sometimes the first thing to go. For example, I don't think HN has a reason to not allow voting w/o JS. I think there's a bit of a tendency to use way too large and slow JS frameworks, but I'm interested in ClojureScript now because it seems to be all about eliminating dead code and optimizing.

[0] https://torchbox.com/blog/torchbox-has-dropped-drupal/

-----

3 points by i4cu 84 days ago | link

> I read a blog post[0] about Wagtail,....because it's more like a CMS framework...

Yeah neither Drupal nor Wagtail sound remotely appealing to me. A CMS, in general terms, is just that: a Content Management System. Now that's pretty broad with lots of room for products which are both good and bad.

Personally I'm interested in the Business Intelligence space where people build Apps, only I'm targeting companies who wish to empower their Business Analysts (or specifically the blue to 'purple people') to build apps and streamline inefficient IT processes.

I'm not sure if BI apps are considered a CMS or not, but when I read that 'trap' article I couldn't help but relate.

> I think I'm just really pro progressive enhancement, and it's sometimes the first thing to go.

Well progressive enhancement is not, not using JS.

Progressive Enhancement is pretty much the opposite of Graceful Degradation. In GD you fallback to allow lesser technologies to handle the workload, where PE is starting with limited functionality and build up incrementally to gracefully handle the workload. JS is often what is used to achieve PE.

> I think there's a bit of a tendency to use way too large and slow JS frameworks, but I'm interested in ClojureScript now because it seems to be all about eliminating dead code and optimizing.

Yep.

All I can say here is that automation and the benefits that comes from that will have a cost. Your product/app/page will contain larger files which do some amount of work for you.

Developers have a tendency to see 'frameworks' from a maximal code efficiency perspective, but frameworks really are all about lessening the $ cost, the work burden, time to market and the operational maintenance. The argument is always "If you're building a blog you shouldn't need a framework." And that's true, but most frameworks are not built for making blogs, they're built for greater things - however if said framework makes it easier for person A to do thing X, even if it's just a blog then, really, it's hard not to see it happening (even though developers don't like to see it).

Frameworks, really, are for when large tailor made products become nightmares to manage, that's when they become the go to "solution" and start to shine. Modern day web development has a lot of pitfalls and will require a skillset that not everyone has. Not everyone can make dynamic apps that don't get bogged down by limiting factors like the DOM tree (cluster fuck), rendering/paint (bottle-necks), and single threaded environments (the async data gotcha's). Frameworks can help with all this, but it's at a cost. The file size is bigger, it's not Free Software, it uses JS and you have the potential to be caught-up in a CMS trap.

-----

3 points by hjek 80 days ago | link

> Well progressive enhancement is not, not using JS. Progressive Enhancement is pretty much the opposite of Graceful Degradation.

Yea, exactly. I'm OK with JavaScript being used for better UX as long as core functionality works w/o JS. From W3C:

> So, graceful degradation is the practice of building your web functionality so that it provides a certain level of user experience in more modern browsers, but it will also degrade gracefully to a lower level of user in experience in older browsers. This lower level is not as nice to use for your site visitors, but it does still provide them with the basic functionality that they came to your site to use; things do not break for them.[0]

If it is assumed that voting is part of the basic functionality of HN, then HN does PE wrong by breaking it when there's no JS. It's a relatively recent change to HN and Anarki doesn't suffer from that issue.

Yet it's neat that HN uses JS to prevent page reloading on voting. I'm just doing no JS at all on my own project here to make sure I don't accidentally rely on it, because I don't really trust myself to use it in moderation.

> Frameworks can help with all this, but it's at a cost. The file size is bigger,

Yea, they're beneficial, but heavy. HN front page: 62K. HN search: 1.19M. Did they really need Angular for that search input form? That's where ClojureScript looks promising though: Their `helloworld` example is just 20K.[1]

[0]: https://www.w3.org/wiki/Graceful_degradation_versus_progress...

[1]: https://clojurescript.org/guides/quick-start

-----

3 points by i4cu 80 days ago | link

Obviously you're more into graceful degradation than progressive enhancement.

My idea of graceful degradation is falling back to a message that says "sorry, not going to happen!" :)

So, obviously, I'm more into progressive enhancement than graceful degradation.

> ClojureScript looks promising though...

Well to be fair, ClojureScript is not a full fledged framework; It is a framework, but really it's more of a compiler with some library functions. Reagent [1], for example, is a library that bridges the gap between ClojureScript and React. So I'm not sure it's fair to compare ClojureScript to these full fledged frameworks... you're still correct though, in that ClojureScript alone can produce apps with a smaller footprint.

That said & just to compare, last time I checked, React and Elm are appx. 42-45kb, Angular is 90kb. So HN search, obviously need to add their own code to bring it in at 1.19M.

My app, written in pure Clojurescript, is currently at 90kb minified. I hope to bring that down, but chances are the first release will actually be a little larger.

1. https://reagent-project.github.io/

-----

2 points by hjek 79 days ago | link

> My idea of graceful degradation is falling back to a message that says "sorry, not going to happen!" :)

Hilarious! A degradation for sure but the graceful part of is questionable.

-----

3 points by hjek 85 days ago | link | parent | on: Show Arc: Debate (very alpha)

> What parts/features do you want to take from each, and why do you think they should coexist in a single product?

DropBox/WeTransfer/Google Drive/OneDrive is just what people use to send larger files. I'm not a fan of those sites, but I have observed that people I know find Filezilla and FTP very intimidating. There's some other free apps for this, but either they're in PHP or they're too complicated to install or use or hack on. Droopy[0] works good for this, so as a start I just cloned what Droopy does; just to check whether Racket/SQLite is fast enough for this use case. (It is)

I like RSS as an idea and the fact that most sites have RSS feeds, but I think it's underappreciated by non-techies, who think that Facebook or Twitter are the only place you can "follow" stuff. For friends of mine to even consider using RSS for anything, I think it needs to be more accessible. I use Newsbeuter for reading RSS but I would never recommend it to non-techie friends, and it has some annoying bugs: Sometimes text is missing, podcast download is flaky at best so I have to copy the url out at get it with curl, and the interface becomes unresponsive when there's many feed items. So I'm thinking of giving it a try to make a web-based RSS reader that encourages sharing and that at very least I'd enjoy using myself. I think this would fit naturally with a News-style app, basically just having RSS feed items being shown alongside other people's posts, but perhaps tweaking the ranking in a way that external feeds don't overshadow local content (assuming that external feed items are votable). Some non-techies have shown me the Feedly app, which (I think) uses RSS, and (I presume) has some kind of social recommendation system, so I just think it would be nice with a free/libre web app doing something similar.

Then, the HN/Lobsters part is basically about having a minimalist web forum with tree structure replies and well thought out ranking algorithms and spam handling, instead of this thoughtless phpBB-style newest-first unstructured mess. One thing Lobsters does right here is that it notifies you when someone replies to a comment of yours. On HN it's possible for someone to reply and you just won't notice because it's so deeply buried in old threads. But I like all the different ways you can sort/view the content on HN.

Also, I've had some painful episodes trying to back up Wordpress sites. It's not pleasant, because there's little distinction between code and content which is stored in a mish-mash of database entries and folders. WP barfs all over the disk. That's something HN does right, because all the content is in the `www` folder. But, then file upload to HN is not really a realistic thing.

So I'm just trying to mix-and-match things I like from different software. A lot of ideas. Haven't gotten far yet! But I guess it's ok to share work-in-progress here.

If I didn't have dockerphobia and mild JS-intolerance, I'd probably just be running Mastodon or something.

[0]: https://github.com/stackp/Droopy/issues?q=is%3Aissue+is%3Acl...

-----

2 points by akkartik 85 days ago | link

I'm wondering:

1. Are you trying to build an RSS reader? Or do you want to support RSS versions of pages on your site?

2. Are you building a file transfer service? Or are you imagining that people will want to share files on a HN-like website? I'm not sure why that would be a common use case.

-----

2 points by hjek 84 days ago | link

> 2. Are you building a file transfer service? Or are you imagining that people will want to share files on a HN-like website? I'm not sure why that would be a common use case.

File upload wouldn't make sense on HN, Arc Forum or Lobsters, and I get that it's entirely on purpose that it's not present on those sites.

But I've been hosting a News site, and those of my friends who use it often submit links to something they've put on Dropbox or Google Drive, so I'm simply observing that this use case is present and that file upload is missing on my site. Perhaps it's because it's a different type of exchanges: a guitarist uploading a recording of a Charlie Parker solo, an artist uploading a drawing, etc.

Well, perhaps I should be using $CRAPPY_PHP_CMS_WITH_FILE_UPLOAD instead of News, but why can't I have well-structured content and file uploads at the same time?

It's also about future extensibility, ways of presenting these file uploads that I haven't thought about yet. I do occasionally write PHP for money. I don't have a very high opinion of that language, and I'd rather make something from scratch in Racket than write it as a Drupal plugin. Given the relative quantities of Drupal plugins and Racket web apps, that might be an unpopular opinion, but it shouldn't seem too strange on this forum. I'd prefer to make custom interactive web sites by extending a code base in Racket rather than PHP.

It's actually also for the use-case of being off-the-grid, yet needing to send/receive files to people in the same room, but not being able to find a USB stick. That situation happens surprisingly often for me. A zero-config web app is useful here because everyone have a browser on their computer (whereas not everyone have FTP / SSH / SMB).

> 1. Are you trying to build an RSS reader? Or do you want to support RSS versions of pages on your site?

I plan to do both. Building a social RSS reader integrated in a News-like app. And this News-like app would provide RSS feeds in the same way Anarki does. I image it wouldn't be too difficult.

-----


I'm somewhat disoriented by the very first example[0]. How is a newcomer meant to grok how this program prints out 42?

    bb/copy-to-EBX  2a/imm32
    # exit(EBX)
    b8/copy-to-EAX  1/imm32
    cd/syscall 0x80/imm8
This is not meant to criticize, but just as feedback from a real assembly newcomer, since this is in your project description:

> It would make it easier to write programs that can be easily understood by newcomers.

[0]: https://github.com/akkartik/mu/blob/master/subx/examples/ex1...

-----

2 points by akkartik 85 days ago | link

Absolutely valid criticism. I'd love to hear more about what you did between seeing the link here and navigating to that example program. I've been trying to build a path to gradually take programmers to an understanding of (this particular unconventional style of) assembly programming. For example, I'm curious how much of the Readme you read, and if you happened to notice that the Readme has an orientation on the x86 processor.

I also made a couple of tweaks to this particular example. I hadn't looked at it in a while. Thank you! https://github.com/akkartik/mu/commit/d6535f3382

-----

2 points by hjek 85 days ago | link

I read the first section of the readme without really understanding much but also not expecting to as I don't know x86 assembly. Then I decided to at least give the examples a superficial look as I'd noticed the word newcomers in the readme. But I couldn't see the number `42` in a program meant to print `42`, so that's where I gave up.

Is this meant to be a tutorial for assembly noobs?

For comparison I think your readme for Wart[0] is more welcoming: Briefly explaining what it is and how to run it, and then straight onto a simple example that people can actually try out.

[0]: https://github.com/akkartik/wart

-----

2 points by akkartik 85 days ago | link

That's a good point. I have similar instructions here, but they're in the second section, 3 screens down..

The audience is assembly-curious programmers, but you aren't expected to know any assembly. I just want to try to hook anyone interested in the goal. If you're interested in a stack you can understand from the ground up, I'm willing to try to explain things to you.

-----

2 points by hjek 84 days ago | link

I might just be outside the target audience, for now. I don't even know any C. Realistically, I think it would have to be spoon-fed to me in some Bret Victor-esque crocodiles and eggs[0] manner for me to not lose focus.

I went through this absolutely fantastic SQL tutorial this week. Perhaps you might find their list of pedagogical principles[1] useful?

I think one thing that potentially could tempt me into low-level code would be making cool tunes[2][3].

[0]: http://worrydream.com/AlligatorEggs/

[1]: https://selectstarsql.com/frontmatter.html

[2]: https://www.youtube.com/watch?v=GtQdIYUtAHg

[3]: https://www.youtube.com/watch?v=qlrs2Vorw2Y

-----

2 points by akkartik 84 days ago | link

I just made some tweaks to the Readme. What do you think?

https://github.com/akkartik/mu/commit/4650c8188f

https://github.com/akkartik/mu/blob/master/subx/Readme.md

-----

2 points by hjek 84 days ago | link

Yea, I think that's more inviting.

I got to try out the point of compiling and trying out your programs now. `ex8`, `ex9` and `ex10` all segfault here.

Some time ago I was at a wedding, and I was terribly bored, until I found out that the guy to my left was writing washing machine software in assembly. In a way it seems awfully primitive, e.g. your `ex11.subx` is 350 lines long and prints out `.......` but I guess in certain systems it's the only option, and what's underneath it all in any system.

-----

2 points by akkartik 84 days ago | link

Thanks for trying them out!

Those examples expect arguments at the commandline, and I chose not to perform error checking for an example :) The focus lay elsewhere for them. See the comment at the top for each.

ex11.subx is running a test for each of those dots :)

-----

3 points by hjek 85 days ago | link | parent | on: Show Arc: Debate (very alpha)

This is what's happening with my "I'm gonna rewrite News in Racket so I can get fast file uploads"-project. I settled on SQLite instead of Datalog, because SQLite is fast.

The score of an item is derived from the votes, not just a stored number. This should make `unvote` easy to implement.

Also, user text input is not forgotten, so there's no need for `unmarkdown`. (However I'm not claiming that my markdown implementation is appropriate)

Comment tree is displayed as list of lists, so folding should be easy to implement.

-----

3 points by hjek 90 days ago | link | parent | on: Ask: Collapsable Comments

I was looking at implementing that in Anarki a while ago thinking it would be simple.

But take a look at how it's implemented on HN. It's quite ... hacky, to say it nicely.

First, the way comments are represented in the HTML is as table rows stacked on top of each other, and indentation is done by stretching a transparent 1x1 gif. Assuming collapsible comments are to be implemented in JavaScript, you're in a bit of a pickle, because the comment tree has been flattened into a long list thereby making it difficult process in a sane way.

So how does HN do it? Well, have a look at the `ind` function in hn.js[0]:

    function ind (el) { return (byTag(el, 'img')[0] || {}).width }
Oh, yes, there is actually a function that returns the width of the invisible strecthed 1x1 gif used for indentation. And, `kidsOf` is implemented using `ind`, and so on.

Some time back, I changed Anarki to use fixed-width spaces for indentation in order to work on text-only browsers. I'm not sure that is any better, so if you want to take the same approach as HN, you'd have to revert Anarki back to invisible image indentation. And maybe you could just nab the collabsible comments code straight from hn.js?

I would personally consider it less hacky to represent the comment tree as a tree of nested list elements in the HTML in the first place. I just don't get this fear of `<li>`.

But whichever way you go about it, you should totally give it a shot!

But, well, even if you implement it in Anarki, it's not gonna go in this forum, I guess.

[0]: https://news.ycombinator.com/hn.js

-----

3 points by krapp 90 days ago | link

>I would personally consider it less hacky to represent the comment tree as a tree of nested list elements in the HTML in the first place. I just don't get this fear of `<li>`.

Apparently pg did it in part to be "unPC" in regards to HTML. (see the linked quote in the 'inline javascript' thread[0].) It is weird that, in the name of exploratory programming, he chose the most complicated and finicky layout imaginable just to stick it to the W3c and their rules, man.

Fortunately, I think Anarki is already moving in the right direction. Table layout should be almost entirely removed (I think polls still use it) and I've been adding css classes and IDs to make the HTML more amenable to scripting. Unfortunately, this means we can't really use anything from HN without rewriting it. There's still a bit more work to do in removing old html like fontcolor, etc.

But the interesting question would be where to store state? HN appears to have endpoints that handle it (?collapse=id) so I assume there is just a list of closed ids for each user somewhere on the server. It could probably also be done with local storage but that wouldn't persist across browsers.

[0]http://arclanguage.org/item?id=20788

-----

3 points by hjek 89 days ago | link

> But the interesting question would be where to store state? [...] It could probably also be done with local storage but that wouldn't persist across browsers.

Cool that you're working on this. Storing state on the server would also allow for it to work w/o JavaScript. (Yes, yes, I know, maybe everyone are not that much into progressive enhancement.)

-----

3 points by krapp 89 days ago | link

I'm working on improving the HTML, I don't know when if ever I'll get around to collapsible comments.

I was just pointing out that HN's own implementation is server-side, but doesn't have to be. As with voting, the js just makes changes to the DOM that shadow the actual work on the backend. I have no idea how to do it efficiently, though, since presumably each close/open operation would also mean an http request and possibly a file write.

-----

3 points by i4cu 89 days ago | link

> I have no idea how to do it efficiently, though, since presumably each close/open operation would also mean an http request and possibly a file write.

Which is the same for voting and page generation.

ie. Right now there's a big cost on the servers because all the work is done on the servers. If you start looking at it from the perspective of not adopting that cost then you might as well say the same for voting + all the html creation and just write the whole thing in js where you only fetch data.

This is the slippery slope that lead me to writing apps in clojurescript. For me, the workload may get increased, but much of the operational costs get distributed across the users and on their hardware.

-----

3 points by hjek 88 days ago | link

> Which is the same for voting and page generation. [...] Right now there's a big cost on the servers because all the work is done on the servers.

Yea, I don't think something like checking whether a comment is member of the list of hidden items by a user would really add workload of any significance.

> [...] you might as well say the same for voting + all the html creation and just write the whole thing in js where you only fetch data.

Does that not lead to an awful lot of traffic sometimes? (I'm imagining a version of News that would transmit all submitted content to let the client do the sorting and searching instead of doing it on the server.)

-----

3 points by i4cu 88 days ago | link

> I don't think something like checking whether a comment is member of the list of hidden items by a user would really add workload of any significance.

I don't think so either. My comment was that "all the work is done on the servers". For the whole app. That is looking at all of the cost in aggregate (every interaction requires a http request, and requires throttling, session handling, authentication, html page generation, and so on....).

> Does that not lead to an awful lot of traffic sometimes? (I'm imagining a version of News that would transmit all submitted content to let the client do the sorting and searching instead of doing it on the server.)

Sure if you fetch all data unsorted, but I wasn't suggesting (or at least thinking) anything like that. I was just suggesting the html creation and many interactions that currently represent at least half if not most of the workload the server operations are currently doing.

-----

3 points by i4cu 89 days ago | link

> Storing state on the server would also allow for it to work w/o JavaScript.

I agree for this case (surprise, surprise...). This app was/is designed to work without js (mostly). If there's much more of a departure from this design and any real dependancy on js begins, well really the whole app should get re-written.

-----

2 points by hjek 93 days ago | link | parent | on: Ask: Why is there no "save-list"?

Yep. Or change `save-table` to be an extension of `writefile` using `defextend`:

   (defextend writefile (val name) (is (type val) 'table)
     [the body of the save-table function here]

-----

2 points by rocketnia 93 days ago | link

Even if you merge `writefile` and `save-table` like this, but not `readfile1` and `read-table`, then people still need to know, at development time, what type of data is in the file in order to read it, so they might as well use a type-specific way to write it as well. Unfortunately, merging `readfile1` and `read-table` isn't really possible, since their serialized representations overlap; they can't reconstitute information that was never written to the file to begin with.

From a bigger-picture point of view, this seems like it would become a non-issue once Arc had its own reader. I assume the problem with reading tables using `read` is that Racket's reader constructs immutable hashes. An Arc-specific reader would naturally construct Arc's mutable tables instead.

Doesn't Racket's reader give us similar problems in that it reads immutable strings and cons cells, too? So these problems could all be approached as a single project.

In the short term, it's not a project that would need a whole new reader. It could just be an adaptation of Racket's existing reader... something like this:

  (define (correcting-arc-read in)
    (let loop ([result (read in)])
      (match result
        
        ; TODO: See if this should construct a Racket mutable cons cell
        ; instead (`mcons`). Right now this just creates an immutable
        ; one, which should be fine since Arc uses an unsafe technique
        ; to mutate those.
        [(cons a b) (cons (loop a) (loop b))]
        
        [ (? hash?)
          (make-hash
            (map
              (match-lambda [(cons k v) (cons (loop k) (loop v))])
              (hash->list result)))]
        [ (? string?)
          ; We construct a new mutable string with the same content as
          ; `result`.
          (substring result 0)]
        ; We handle tagged values, which are represented as mutable
        ; Racket vectors.
        [(? vector?) (list->vector (map loop (vector->list result)))]
        
        ; We handle various atomic values. (TODO: Add more of these
        ; cases until we've accounted for every writable type Arc
        ; supports. Alternatively, just make this a catch-all
        ; `[_ result]`.)
        [(? number?) result]
        [(? symbol?) result])))
Writing Arc's `queue` type might be tricky, since that representation relies on sharing. It's possible queues (and other tagged values in general) should have a customized read and write behavior.

-----

3 points by hjek 93 days ago | link

> I assume the problem with reading tables using `read` is that Racket's reader constructs immutable hashes.

Racket also has mutable hashes created using `make-hash`[0] rather than `hash`. It could just be that the tables are not serialised as something Racket reads as mutable hashes when deserialising it back again?

[0]: https://docs.racket-lang.org/reference/hashtables.html#%28de...

-----

3 points by rocketnia 93 days ago | link

"It could just be that the tables are not serialised as something Racket reads as mutable hashes when deserialising it back again?"

I'm pretty sure the Racket reader never reads a mutable hash, but that it's possible for a custom reader extension to do it.

Some of Racket's approach to module encapsulation depends on syntax objects being deeply immutable. In particular, a module can export a macro that expands to (set! my-private-module-binding 20) but which uses `syntax-protect` so that the client of that macro can't use the `my-private-module-binding` identifier for any other purpose. If the lists constituting a program's syntax were usually mutable, then it would be hard to stop the client from just mutating that expansion to make something like (list my-private-module-binding 20), giving it access to bindings that were meant to be private.

I think this is why Racket's `read-syntax` creates immutable data. As for why `read` does it too, I think it's just a case of `read` being a relatively unused feature in Racket. They don't have many use cases for `read` that they wouldn't rather use `read-syntax` for, so they don't usually have reasons for the behavior of `read` to diverge from the behavior of `read-syntax`.

All this being said, they could pretty easily add built-in syntaxes for mutable hashes, but I think it just hasn't come up. Who ever really wants to read a mutable value? In Racket, where immutable values are well-supported by the core libraries, you aren't gonna need it. In the rare case you want it, it's easy enough to do a deep traversal to build the mutable structure you're looking for (like my example `correcting-arc-read` does).

It only comes up as a particular problem in Arc. Arc's language design doesn't account for the existence of immutable values at all, so working around them when they appear can be a bit quirky.

-----

3 points by hjek 93 days ago | link

> I'm pretty sure the Racket reader never reads a mutable hash, but that it's possible for a custom reader extension to do it.

No..?

    > (require racket/serialize)
    > (define basket (make-hash))
    > (hash-set! basket 'fruit 'apple)
    > (write-to-file (serialize basket) "basket.txt")
    > (define bucket (deserialize (file->value "basket.txt")))
    > (hash-set! bucket 'fruit 'banana)
    > bucket
    '#hash((fruit . banana))

-----

4 points by rocketnia 93 days ago | link

The Racket reader reads a seven-element list there, not a mutable hash.

Looks like you're proposing to use a two-stage serialization format. One stage is `read` and `write`, and the other is `serialize` and `deserialize`. At the level of language design, what's the point of designing it this way? (Why does Racket design it this way, anyway?)

I can see not wanting to have cyclic syntax or syntax-with-sharing in the core language just because it's a pain in the neck to parse and another pain in the neck to interpret. Maybe that's reason enough to have a separate `racket/serialize` library.

But isn't the main issue here that Arc's `read` creates immutable tables when the rest of the language only deals with mutable ones? The mutable tables go through `write` just fine, but `read` doesn't read the same kind of value that was written out. If and when this situation is improved, I don't see where `racket/serialize` would come into play.

-----

2 points by hjek 92 days ago | link

> Looks like you're proposing to use a two-stage serialization format.

I wasn't really proposing anything, only pointing out that it's not the case that Racket never can read mutable hashes, and then illustrating that with a code example.

-----

3 points by rocketnia 91 days ago | link

Hmm, all right. I didn't want to believe that was the point you were trying to make. In that case, I think I must not have conveyed anything very clearly in the `correcting-arc-read` comment.

I've been trying to respond to this, which was your response to that one:

"Racket also has mutable hashes created using `make-hash` rather than `hash`. It could just be that the tables are not serialised as something Racket reads as mutable hashes when deserialising it back again?"

In the `correcting-arc-read` comment, I used `make-hash` in the implementation of `correcting-arc-read`, so I assumed your first sentence was for the edification of others. I found something to respond to in the second, which kinda pattern-matched to a question I had on my mind already ("Can't the Racket reader just construct a mutable table since what was written was a mutable table?").

As for my response to your "No..?"...

One of the purposes of `correcting-arc-read` is that (when it's used as a drop-in replacement for Arc's `read`) it makes `readfile1` return mutable tables. So if anyone had to be convinced that a reader that returned mutable hashes could be implemented at all in Racket, I thought I had shown that already. When it looked like you might be trying to convince me of something I had already shown, I dismissed that idea and thought you were instead trying to clarify what your proposed alternative to `correcting-arc-read` was.

Seems like I've been making bad assumptions and that as a result I've been mostly talking to myself. Sorry about that. :)

Maybe I oughta clarify some more of the content of that `correcting-arc-read` comment, but I'm not sure what parts. And do you figure there are any points you were making that I could still respond to? I'd better not try to assume what those are again. :-p

-----

3 points by kinnard 92 days ago | link

Sounds like I opened a can of . . . lists . . .

-----

3 points by akkartik 93 days ago | link

I have an old fork (https://github.com/akkartik/arc) that has an extensible generic pair of functions called serialize and unserialize which emit not just the value but also tagged with its type. read and write are built atop them.

-----

More