> Take a page full of intense mathematical notation or an orchestral score and translate it into either full words (i.e.: "integral" in place of the integral symbol) or one, two or three character ASCII mnemonics. You should realize that the original is far more powerful a tool for communicating thoughts, ideas and the subject at hand than a seemingly random dump of ASCII on paper.
I've heard this idea before: have a language that separates the chrome of the top-level syntax from the underlying code.^1 That is, you can have the same language use different syntaxes ^2. This would allow robomartin to have his "notation as a tool for thought", while still having another syntax that's easier to understand, for those that want it.
But, of course, this would be difficult, especially if you want to allow mixing of multiple syntaxes in the same line of code.
For this specific example, you could have aliases for APL tokens to (possibly) multiple J tokens. The reader of the code could decide how to view it.^3 The writer could write whatever he or she prefers. But this doesn't even seem to be enough here; I don't think J and APL have all the same operators; unless you can make APL operators easily by combining J ones, this won't work. Of course, that doesn't mean a newly-designed language won't work.
Also, it's hard enough to get one language adopted by people; trying to get a language with variable syntax must be significantly harder. The toolchain will be an extremely important part of language evangelism; if there's no good way for people who don't use, say, either Emacs or Vim to use this language, no one will.
Perhaps start with an even simpler J version; instead of
avg=: +/ % #
you would write ^4:
avg=: fold(+) divide list-len
Why do I think people would tolerate having multiple syntaxes for the same thing? Let's take a musical interlude here. Now, music is traditionally written on as sheet music: on a staff, with different notes to indicate length, and the vertical position on the staff to indicate pitch. However, for guitars, there's a more common way of writing it: guitar tab. This throws away information like timing, and simply says "fret X on string Y".^5 Like our J-analogue for APL, tab is much simpler; if you can play the guitar, you can understand tab in a few minutes. Staff takes much longer; weeks or months. People don't go back and forth between one or the other; generally, if you're comfortable working with sheet music, you use that if you have the choice, only choosing tab if you don't have sheet music. I don't know if someone's designed a tool to translate between sheet music and tab.
[1] Heck, even Lisp started that way, with M-expressions: https://en.wikipedia.org/wiki/M-expression . That no one used them is possibly an indication this is a bad idea.
[2] It's a fool's argument, but not technically wrong, to say we have that with different languages that compile to assembly, or to C, or scheme, or whatever. That's missing the point.
[3] This sounds like a nice Emacs mode.
[4] Yes; I'm suggesting a "simple" version include the terminology "fold". It's an implementation detail; perhaps this is better:
avg=: +-list divide list-len
[5] Note that guitar tab specifically says which string to use: since a single note can be played multiple ways on a guitar (e.g., the open A string is enharmonically the same to the fifth fret on the low E), guitar tab has information which sheet music does not. Whether this is a benefit or not is hotly debated.
"This would allow robomartin to have his "notation as a tool for thought", while still having another syntax that's easier to understand, for those that want it."
For the past 6 months I've been going to a hackerspace in Oakland every monday evening, and trying to learn how to teach programming to non-programmers. So I've been thinking about this a lot.
BTW, a friend mentioned that APL does indeed have an 'english' mode as a debugging aid. Perhaps it's indicative that people are using the more concise notation in spite of the availability of alternatives.
Also, I just noticed that the same user who has committed to the HN github has a port of Arc to be a Racket language: https://github.com/kogir/rarc-public . Do we know if he's a YC employee? Is this the next version of Arc?
"If you looked at it closely, I made many changes in the spirit of getting something running that PG (and you!) would likely not agree with."
I didn't see the repo while it was online, but I've always looked forward to Arc (or at least Anarki) becoming usable as a Racket language at some point, even if it were an awkward fit. Just how disagreeable are we talking, here? :)
I originally found this on HN (https://news.ycombinator.com/item?id=5979066), but this can be verified by going to the bottom of any HN page and clicking "bugs". I'm excited for the possibility of new releases of Arc.
At a minimum, gen-nested-css needs to be a macro, not a function.
But also, recursive macros are hard. You need to know whether you'll recurse without looking at the values of variables, because macroexpansion time is before runtime.
I'd worry about treating them separately, at least depending how much anarki's stable branch (which is supposed to be very close to vanilla Arc) is emphasized compared to its more experimental branches.
I like the idea of describing Arc 3.1 in the main docs. This way the docs can describe the Arc features people have already strived to keep consistent in projects like Jarc, Rainbow, Arcueid, and Arc/Nu. If other libraries or language variants need their own subpages, those can spring up as necessary. :)
---
A project like this should probably use an "arclanguage.github.io" repo rather than some other repo's gh-pages branch.[1]
The arcfn static site generator may lead to some hassle. The generated website artifacts need to be pushed to the master branch, so they'll be the first thing someone sees when they delve into the repo to make a wiki edit. GitHub goes out of its way to make it easy to edit a repo as though it's a wiki[2], but that method of update won't trigger a very expressive build language[3], let alone anything that supports an Arc-based generator. Unless we have another server that does builds in response to a GitHub post-receive hook[4], in which case why not host the website there instead?
To use a custom generator, or to use Jekyll directly... both of these choices seem to have problems.
Another option would be to do keep Arc code inside <script> tags and run it with something like Rainbow.js, but search engines probably wouldn't index any content generated this way.
Hopefully someone here will be more optimistic about these ideas than I am. ^_^
Thank you for your wonderful ideas, I learn more about github services. :)
Some quick thoughts:
Can we split arcfn docs into two parts: tutorial and reference.
The tutorial part can integrate with current Google Site wiki contents, and can be renderred by Jekyll so it can be more like a wiki.
And the reference part need to be generate locally and then push the static html to the repo.
All those two part can reside on "arclanguage.github.io" repo.
The repo structure may be like this:
arclanguage.github.io/
|-- index.html
|-- tutorial/ ; or move all stuffs to the top dir?
|-- docs/ ; static html. (reference instead of docs?)
|-- _docs/ ; source of docs
|-- anarki/
|-- jarc/
|-- ...
Also, we can use a post receive hooks to generate docs directly.
In ac.scm, in the arc compiler ac, arc strings are translated using ac-string. I've tried instrumenting the output of ac-string, and it seems mutable when it's encountered. And yet it's immutable by the time I return to the prompt:
I tried bisecting the git history, and the stable branch, which still requires mzscheme, has mutable strings. But sometime in 2011 when the master branch switched to using racket and stopped working with mzscheme, strings went immutable again. Still investigating..
---
Back in Feb 2011, waterhouse provided a bugfix for arc's mutable pairs. http://arclanguage.org/item?id=13616. https://github.com/arclanguage/anarki/commit/cea8a4c5e9. This change requires a racket-only lib, and so arc stopped working with the old mzscheme versions. Prior to it, modifying strings worked in mzscheme but not in racket. So it seems to be something about the move from mzscheme 372 to racket.
---
Update 34 minutes later: It seems eval in racket emits immutable strings even when given mutable strings. Since everything passes through racket's eval it doesn't matter how much arc twists and turns to avoid immutability.
That's a good idea. Did the tests pass without your changes?
I've added a few piecemeal tests over the years (all the .t files in the repo), and there's also some tests in my curated repo (http://github.com/akkartik/arc). All those seem ok..
Update 1 hour later: almost all rainbow tests pass! I had to disable the dfn tests, and the ssyntax tests at the bottom of core-evaluation-test were hanging. Other than that it's all good.
There's still a couple of syntax tests that are failing, likely because of test harness issues. And I'd like to unify all the different tests into a single framework. For future work..
---
Update 43 minutes later: it turns out rainbow's ssyntax precedence rules were different. Perhaps anarki changed at some point. Those tests are now fixed.
Well, it depends if you're talking vanilla Arc, or a different implementation.
If you want to go with base Arc, you can pass a dictionary in, something like this:
(def greet ((o arg-dict (obj)))
(prn "Hello there, "
(or arg-dict!person "friend")
"! Would you like "
(or arg-dict!thing-to-offer "some ice cream")
"?"))
arc> (greet)
Hello there, friend! Would you like some ice cream?
"Hello there, "
arc> (greet (obj person "Darth Vader" thing-to-offer "a lightsaber"))
Hello there, Darth Vader! Would you like a lightsaber?
"Hello there, "
arc> (greet (obj thing-to-offer "two lightsabers"))
Hello there, friend! Would you like two lightsabers?
"Hello there, "
arc>
You could, I suppose, treat a rest argument as a list of (keyword argument) pairs:
(def greet2 arg-list
(let args (pair arg-list)
(prn "Hello there, "
(or (alref args 'person) "friend")
"! Would you like "
(or (alref args 'thing-to-offer) "some ice cream")
"?")))
arc> (greet2)
Hello there, friend! Would you like some ice cream?
"Hello there, "
arc> (greet2 'person "Darth Vader" 'thing-to-offer "a lightsaber")
Hello there, Darth Vader! Would you like a lightsaber?
"Hello there, "
arc> (greet2 'thing-to-offer "two lightsabers")
Hello there, friend! Would you like two lightsabers?
"Hello there, "
arc>
Note: this has no error checking, but the failure mode isn't awful:
arc> (greet2 'person)
Hello there, friend! Would you like some ice cream?
"Hello there, "
arc>
You can mix this with required parameters:
(def greet3 (emotion . arg-list)
(let args (pair arg-list)
(prn "Hello there, "
(or (alref args 'person) "friend")
"! I'm "
emotion
" to see you. Would you like "
(or (alref args 'thing-to-offer) "some ice cream")
"?")))
arc> (greet3 'happy)
Hello there, friend! I'm happy to see you. Would you like some ice cream?
"Hello there, "
arc> (greet3 'enraged 'thing-to-offer "to be murdered")
Hello there, friend! I'm enraged to see you. Would you like to be murdered?
"Hello there, "
arc>
I haven't used these; I've merely come up with them on the spot. No doubt other people have come up with better ideas.
Downsides include not having a good way to set defaults -- you have to supply the default each time in the code you use it. Alternately, you can put the body in a function that requires each argument, then in the "regular" function, supply the default as an argument to the helper:
(def greet4 (emotion . arg-list)
(let args (pair arg-list)
(greet4-helper emotion
(or (alref args 'person)
"friend")
(or (alref args 'thing-to-offer)
"some ice cream"))))
(def greet4-helper (emotion person thing-to-offer)
(prn "Hello there, "
person
"! I'm "
emotion
" to see you. Would you like "
thing-to-offer
"?"))
arc> (greet4 'bored)
Hello there, friend! I'm bored to see you. Would you like some ice cream?
"Hello there, "
arc> (greet4 'bored 'thing-to-offer "to go away")
Hello there, friend! I'm bored to see you. Would you like to go away?
"Hello there, "
arc>
Note that you can't explicitly pass nil this way:
arc> (greet4 'bored 'thing-to-offer nil)
Hello there, friend! I'm bored to see you. Would you like some ice cream?
"Hello there, "
arc>