Arc Forumnew | comments | leaders | submit | kinnard's commentslogin
3 points by kinnard 20 hours ago | link | parent | on: Ask: Why is there no "save-list"?

Is it straightforward to change them to be consistent?


2 points by akkartik 19 hours ago | link

Yup, just rename the macro and search-and-replace all calls. Then try running all tests! (Updating incompatibilities at the top of arc.arc is also appreciated.)


2 points by hjek 19 hours ago | link

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 16 hours 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?)
              (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.


2 points by hjek 16 hours 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?



1 point by rocketnia 8 hours 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.


1 point by hjek 1 hour 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.


    > (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))


2 points by akkartik 12 hours ago | link

I have an old fork ( 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.


Well, I don't know about that . . . lisp seems pretty supernatural to me.


Thank you! I don't think there's any example of a systems which fulfills the desired properties of a Blockchain without a native cryptocurrency. I'm skeptical of the notion of intrinsic worth. I think things have value because humans value them. Gold has a lot of utility, you probably use it frequently without knowing it. I think it's more accurate to say that Blockchain uses Bitcoin, since Blockchain was the solution necessary to create Bitcoin(speaking of course before the advent of derivative cryptocurrencies+blockchains), but really they're codependent. You need bitcoin to write to Bitcoin's blockchain. That's very useful.


1 point by i4cu 13 days ago | link

> You need bitcoin to write to Bitcoin's blockchain.

Right so, Blockchain is a methodology for a cryptographic system of record with transaction capability, and doesn't have to be used for currency, even though that's how everyone is using it. When you simplify it down to a 'system of record' then other use cases become new opportunities. I don't currently have useful ideas outside of currency, but my point was that Buffet doesn't need to understand the details of the methodology (bottom up) to establish an understanding of Bitcoin for investment purposes.

Even as a currency it is valuable provided that it gets tied to something tangible/meaningful. Personally I'm interested in ethereum because of its smart contracts and dapps.

> Gold has a lot of utility,

I'm aware that gold has some utility, so you are correct that I shouldn't haven't stated 'no utility', but gold's utility is not capable of justifying the price on the market. If gold was not being held as asset for the sake of being held as an asset, based on its rarity, then its market value would plunge to the near bottom.

> I'm skeptical of the notion of intrinsic worth. I think things have value because humans value them.

Right so, Gold has value because humans value it, but its value on the market is not tied to its intrinsic worth it's tied to its rarity alone. And that's the point of highlighting intrinsic worth over a human valuation. The value stability/durability is tied to its intrinsic worth.

The overall point is that Buffet is a value investor that's known to use intrinsic worth as the value measure. This is why Buffet hates both gold and Bitcoin. So let's not assume that he doesn't understand. Bitcoin's value is not stable because it's not tied to anything tangible. Even $ are just notes, but they are backed by a gov't which is why they have intrinsic value and therefore much more stability (or as much stability as the gov't/country provides).

note: made some edits to support correct word use.


1 point by kinnard 929 days ago | link | parent | on: How Lisp is going to save the world!

This is awesome.


1 point by kinnard 947 days ago | link | parent | on: ASK: How to read user input?

I believe what you're looking to do is assign what's "read" in to a variable e.g.:


(def getUserPrompt ()

    (= msg readline)

    (pr msg)



1 point by mpr 947 days ago | link

Yes, but I'm using the msg arg as the prompt text. Example:

    arc> (= x (prompt "> "))
    > this is the user text
    arc> x
    "this is the user text"
I ended up hacking the ac.scm file to throw away the first newline after an expr is (read). It works for now.


2 points by kinnard 947 days ago | link

I think I understand. You want a function that prints arbitrary user prompts and then takes in user inputs?

You should share your hack!


3 points by mpr 947 days ago | link

Yep, thats the idea. Anyway, here is my hack, in all its hackish glory:

    (define (trash-line c)
      (if (equal? c #\newline)
        (trash-line (read-char))))

    (define (tl2 interactive?)
      (when interactive? (display "arc> "))
      (on-err (lambda (c)
                (set! last-condition* c)
                (parameterize ((current-output-port (current-error-port)))
                  ((error-display-handler) (exn-message c) c)
                (tl2 interactive?))
        (lambda ()
          (let ((expr (read)))

            ;; HACK located here
            (trash-line (read-char)) ; throw away until we hit the newline

            (if (eof-object? expr)
                 (begin (when interactive? (newline))
            (if (eqv? expr ':a)
                (let ((val (arc-eval expr)))
                  (when interactive?
                    (write (ac-denil val))
                  (parameterize ((current-namespace (main-namespace)))
                    (namespace-set-variable-value! '_that val)
                    (namespace-set-variable-value! '_thatexpr expr))
                  (tl2 interactive?)))))))
So I call the trash-line function after the expr is read, but before it is eval'd by arc, so that there is not leading #\newline in the input buffer.

This does seem to work for the readline'ing I was doing yesterday. Probably doesn't handle all cases.

As akkartik mentioned above, this hack is obviated by running scripts in batch mode.


Edit: this change is in my ac.scm file around line 1250


2 points by akkartik 947 days ago | link

I like it! I don't think it'll break anything; can you send a pull request? Then we'll be able to run such code reliably at the repl! That would be sweet.

Edit 38 minutes later: hmm, there's one issue. Right now you can type multiple expressions in on a single line, but this change would drop everything after the end of the first expression. A better approach would be to drop only whitespace and stop at the very first non-whitespace character.


2 points by mpr 947 days ago | link

Thanks! Yeah, I am aware of that bug, and was kind of ignoring it ;) I'll implement your suggested fix then send a pull request.


3 points by mpr 946 days ago | link

Pull request submitted


1 point by kinnard 947 days ago | link | parent | on: ASK: What is Lisp Enlightment?

I now disagree: I realized my cognitive process might actually be the lambda calculus.


Surprised this story got no love. It's providing a powerful new medium/platform for lisping . . . I expect it to have a big impact on the size and character of the lisp community.


1 point by akkartik 948 days ago | link

Seemed like PR:


5 points by kinnard 949 days ago | link | parent | on: Can't access my server

This is a stab in the dark but have you opened the port to receive connections from other "machines". Maybe the firewall is blocking incoming connections.

Also, it might help if you copy exactly your terminal input.

Additionally, the github is another resource though I'm not sure this is an arc issue:


2 points by ca 949 days ago | link

Many thanks for helping with this.

This is what the terminal looks like when I run ./run-news

$ ./run-news rm: cannot remove 'www/news/story/*.tmp': No such file or directory load items: ranking stories. ready to serve port 8080

To quit: arc> (quit)

  (or press ctrl and 'd' at once)
For help on say 'string':

  arc> (help string)
For a list of differences with arc 3.1:

  arc> (incompatibilities)
To run all automatic tests:

  $ hg clone

  $ ./arc

  arc> (load "tests.arc")
If you have questions or get stuck, come to

Arc 3.1 documentation:



4 points by kinnard 949 days ago | link

I believe that error occurs because the news app is attempting to `rm` a temporary dir that hasn't been created yet:

It may be related to what's being discussed here:

But I am able to successfully visit http://localhost:8080/ after running `./run-news`. Alternatively the (nsv) command also works for me.

So I'm not able to reproduce the error that you're getting.

Any luck investigating your firewall?


4 points by ca 946 days ago | link

It's up!

The issue was network (firewall) related. I simply destroyed the firewall (it's on VM so am not concerned about security on this one). On ubuntu that amounted to removing the IPtable rules.

Am looking forward to putting this behind Nginx and seeing how that goes.

Thanks for sticking with me kinnard. It's very much appreciated. Have a great week.


1 point by kinnard 945 days ago | link

Haha, happy to help, would love to see what you're building.

Pay it forward.


Anyone down to develop an arc scripting language for VR?


1 point by kinnard 950 days ago | link | parent | on: Why Lisp?

Analysis of homoiconicity by comparing S-expressions, json, and xml is pretty compelling compared to all the other lisp evangelism I've read.