Arc Forumnew | comments | leaders | submitlogin
Poll: ssyntax
7 points by almkglor 5814 days ago | 38 comments
user-definable ssyntax is now implemented on the git, although using the user-definable ssyntax breaks exit-on-eof for some reason.

So here are some proposals for ssyntax

No. Do not add ssyntaxes unless and until pg adds new ssyntax and/or a pg-sanctified user-definable method of adding ssyntaxes
3 points
->foo == [coerce _ 'foo]. e.g. instead of

  (coerce (coerce x 'num) 'int)
use

  (->int:->num x)
3 points
foo<- == [coerce _ 'foo]. like above but opposite direction

  (int<-:num<- x)
2 points
foo?bar == (is foo bar)
2 points
foo? == [isa _ 'foo]. Instead of

  (isa x 'string)
use

  (string? x).
Can be made compatible with the previous option actually (the system differentiates between prefix, postfix, and infix ssyntaxes)
10 points
foo? == [is _ foo]. Instead of

  (some [is _ fun] l-of-fns)
use

  (some fun? l-of-fns)
2 points
foo&&bar == (andf foo bar). Instead of

  (and (acons x) (car x))
use

  (acons&&car x)
4 points
foo//bar == (orf foo bar). Instead of

  (or (alam x) (anapp x))
use

  (alam//anapp x)
Can't use "|" because of reader issues ^^
4 points
foo&&bar == (and foo bar).
0 points
foo//bar == (or foo bar).
0 points
:foo == 'foo. Instead of:

  (scanner
    'car x
    'cdr (something x))
use

  (scanner
    :car x
    :cdr (something x))
Yes, the system can handle this syntax even with : as infix being used for composition
0 points
$foo == [map foo _] . Instead of:

  (map carif ls)
use:

  ($carif ls)
3 points


3 points by conanite 5814 days ago | link

I like && & // for andf/orf

: instead of ' doesn't look so good for quoting lists -

  :(a b c)
It's a little unhappy, no? And it makes :foo look like a ruby symbol, but arc symbols and ruby symbols don't work in quite the same way

-----

2 points by absz 5814 days ago | link

My understanding is that ssyntax can only be part of symbols, so you wouldn't be able to write :(a b c). At any rate, I think the idea of using it is to ape keyword parameters in Common Lisp.

Personally, I like & and | or andf and orf, but as almkgor mentioned, | is taken for "odd" symbols (e.g. '|this is a symbol|), using just / would interfere with things like w/stdout, and using & and // would be asymmetric. In any case, having some ssyntax for andf and orf is definitely a good idea.

-----

2 points by eds 5814 days ago | link

Taking inspiration from discreet math, we could use ∧ and ∨ as andf and orf, respectively. This would be in line with pg's current use of ~ as not. On the other hand, maybe we shouldn't make use of non-ascii characters... (or else you get APL et al)

-----

3 points by absz 5814 days ago | link

I would say use ^ and v, but something tells me that disallowing a v in identifiers would be a bad idea (e.g. eval) ;)

My biggest problem with using Unicode is that it's often a pain to type. The Mac gets this the most right of any platform I know, but even so, it's (a) not a standard, and (b) mostly alphabetic. Which is a pity, really, since those do make the most sense.

According to Wikipedia (http://en.wikipedia.org/wiki/Logical_conjunction and http://en.wikipedia.org/wiki/Logical_disjunction), we could use ∧, ^, &, &&, or . for andf and ∨, v, |, ||, or + for orf. + might not be bad, but it's probably a little too common.

-----

1 point by eds 5813 days ago | link

> My biggest problem with using Unicode is that it's often a pain to type.

Agreed. We might be able to add a hook to arc-mode in emacs to make it more convenient, but reminds me even more of APL (which if I recall correctly required a custom keyboard to type).

> + might not be bad, but it's probably a little too common

I like +. While + does get used in symbols occasionally (most notably in arithmetic), I can't think of any cases where it gets used in the middle of a symbol.

EDIT: On second thought, when I use plus outside of a programming context, I usually mean and, so it might be confusing to use + as 'andf.

-----

1 point by absz 5813 days ago | link

The problem with "adding a hook to arc-mode in emacs" is that then you alienate everyone not using Emacs. And that's a good point about + being used to mean &.

-----

1 point by eds 5812 days ago | link

Or if using vi you'd add a vi macro, etc.

But point is, whatever editor you did use would need special configuration to type those characters.

-----

1 point by helium 5812 days ago | link

· would be andf + would be orf

-----

1 point by eds 5812 days ago | link

How do you type '·' (not '.') on a standard keyboard?

-----

1 point by absz 5812 days ago | link

On a Mac U.S. QWERTY layout, option-shift-9. Same problem, only slightly reduced.

-----

1 point by helium 5812 days ago | link

Using windows: hold the Alt key and then type 250 on the num pad and than release Alt. but you're right, that's not an option.

-----

2 points by sacado 5813 days ago | link

"maybe we shouldn't make use of non-ascii characters" : why not ? Characters like λ have their place in a Lisp, and I think ∧and ∨ have their place too. Anyway, such characters wouldn't be used very frequently (do you often use andf & orf ?) and could be ignored if typing them is too painful. That's better than consuming ASCII characters that sometimes fit well in symbol names, IMO.

-----

9 points by kens 5813 days ago | link

I think it would be hilariously ironic to make non-ASCII Unicode characters part of Arc's syntax and functions.

A few proposals for giving functions new names: ☢ for atomic, ✄ for cut, ✔ for check, ⌚ for time, ⌛ for sleep, ☠ for kill-thread, ☇ for zap, ♭for flat.

-----

4 points by almkglor 5813 days ago | link

Given that it didn't originally have good Unicode support ^^

-----

4 points by sacado 5813 days ago | link

lol, I really like the "flat" idea :)

-----

2 points by almkglor 5813 days ago | link

> (do you often use andf & orf ?)

Yes, in arc2c ^^

-----

3 points by sacado 5813 days ago | link

Oh, well, ok then... :)

But anyway, I still think they're not worth loosing an ASCII character, and using mathematical notation would be very useful. It would make code readable by people a little aware of mathematics. That is, most programers. It would be definitely better than arbitrary characters.

Why should we restrict to ASCII anyway ? I mean, a lot of symbols I use are not ASCII anymore (they are accentuated, I'm French so something like 'year is translated into 'année, not into 'annee). Sure, they're hard to type, but are they any longer than they symbol counterpart ? If you type them often, just make them a vi macro (or whatever in your favorite text editor) and you're done.

It might end up looking like APL, for sure, but I think Fortress, Sun's new language designed by Guy Steele, is going that way too. And Steele cannot be wrong :)

-----

5 points by absz 5813 days ago | link

I don't mind non-ASCII, I mind weird non-ASCII. Even in English, we leave ASCII behind: “As I was going to the café—what fun—my naïve friend said…” It's just that I don't know of any keyboard layout that supports ∧ or ∨. I agree that they would look great, as would Fortress.

I wonder if anyone's given any though to using (La)TeX in a language? So that something like (number{\wedge}acons var) would be the same as (number∨acons var)? Or just as a nice way of typing things like Fortress? (Which I agree looks very interesting.)

-----

2 points by almkglor 5813 days ago | link

> Oh, well, ok then... :)

I'd probably use them a lot more often if the syntax was a little easier, which is why I suggested using ssyntax for them. Currently the syntax is ((orf this that the-other) foo), and doubled starting parens feel rather strange to me.

-----

4 points by stefano 5813 days ago | link

I think that user definable ssyntax leads to really unreadable sources if it is used pervasively.

-----

2 points by almkglor 5813 days ago | link

Which is why I'm polling, instead of arbitrarily adding them. ^^

-----

1 point by absz 5814 days ago | link

What about what cchooper proposed in http://arclanguage.org/item?id=4712 : ($car ...) == (map car ...)? That's straightforward to add, if we add a new macro: def-ss-, to add new ssyntax with lower precedence (def-ss+ can be defined by analogy):

  (mac def-ss- rest
    (let pairs (map (fn ((s e)) `(,(string s) ,e))
                    (pair rest))
      `(do (zap [join _ ',pairs]           ssyntaxes*)
           (zap [join _ ',(map car pairs)] ssyntax-strings*))))
  
  (= mac-seval $)
  (def-ss-
    $ (fn lists (apply map R lists))
    $ mac-seval)
. Then we have

  arc> ($car '((1 2) (3 4) (5 6)))
  (1 3 5)
(The reason $ is lower precedence is that then we can write things like $.sin.)

-----

1 point by almkglor 5814 days ago | link

Actually the prefix $ will have to be higher precedence than . if we want to support $.sin syntax.

Basically what is done is, it scans linearly through the ssyntaxes* list, and performs the splitting at the time. So if the list is:

  $ prefix
  $ standalone
  :  infix
  ~prefix
  ~ standalone
  . infix
  ! infix
Then when processing $.sin, it will see the prefix $ first, so it will split it into {$, .sin} and attempt to return a curried 'map with '.sin

-----

1 point by absz 5814 days ago | link

Actually, that's precisely why it has to be lower precedence: we want $.sin to turn into ($ sin), so as to get at trig from mzscheme; if it were to become (map .sin ...), things would die because of the malformed ssyntax in .sin. (I tried it both ways, which is how I figured this out.)

-----

1 point by almkglor 5814 days ago | link

Ah, I think we have a misunderstanding here: from my point of view, objects earlier in the list have lower precedence to objects later in the list. ^^ So your "lower precedence" is my "higher precedence". Basically, it has to do with stuff like:

  foo!bar:qux!quux
which is compiled as:

  {{foo ! bar} : {qux ! quux}}
So !, which is listed later, has higher precedence (it gets grouped more tightly)

-----

2 points by dreish 5812 days ago | link

I wouldn't want to see any of these added to the base language, but I think it's great that the anarki/git allows the user to create these, and I hope that feature makes it into the official language. Lisp is for creating domain-specific languages, and Arc is supposed to be a compact Lisp, so domain-specific syntax seems like a good thing to me.

I'm also biased, because I want to create my own syntax for a message-passing Arc to be used as the object scripting language for a multi-user VR system. (I haven't even started working on a server for it yet -- just the client and the protocol.) So something like:

  (is /parent/owner/id /owner/id)
instead of

  (is (msg (msg parent 'owner) 'id) (msg owner 'id))
I assumed I was going to have to dig into as.scm, but if there's a quicker way to do it, that's less work for me.

-----

3 points by almkglor 5812 days ago | link

Looks like you have to add something like:

  /  (msg L 'r)
capital L means left-associative, so foo/bar/nitz is grouped {{foo / bar} / nitz}.

As an aside, why not <- ? Basically parent<-owner<-id means "send 'id to the result of sending 'owner to parent".

For that matter if an object, such as parent above, is something of very specific type, you can even use the Anarki 'defcall syntax. For example if messageable objects are of type 'messageable, you can do:

  (defcall messageable (o m)
    (msg o m))
which creates the relation:

  (foo bar) == (msg foo bar), if (is (type foo) 'messageable)
Then (msg parent 'owner) is simply parent!owner. If you load the new Anarki ssyntaxes.arc, then parent!owner!id is ((parent 'owner) 'id)

-----

1 point by dreish 5810 days ago | link

Thanks for the tips.

I considered <- (along with a lot of other things), but rejected it because the left-associativity of it seemed counter-intuitive, it didn't stand out as much as slashes, and I want it to stand out because it's inconsistent with symbol syntax, it's confusing with -> which conventionally means type-conversion (and which doesn't break up symbols), and it's three times as much effort to type as /.

Slashes are fairly common in symbols, but not at the beginning (except for / itself), so it's unambiguously parseable, though maybe it won't work with this system, now that I think about it. I don't see how to prevent embedded slashes from meaning anything special without the first slash. I.e., I want foo/bar/nitz to be one symbol, but /foo/bar/nitz to be a symbol and two msg calls. Maybe that's too hairy, but I'd hate to break things like w/uniq.

I guess the general solution to any syntax that is confusing to people is a good syntax-highlighting editor.

-----

3 points by almkglor 5810 days ago | link

Well, for that matter having (foo msg) mean "send msg to foo" would be much shorter, and also shows that Scheme was originally a synchronous message-passing language anyway.

-----

1 point by dreish 5809 days ago | link

Yeesh, why didn't I think of that?

That seems clearly to be the best way to do it. Thanks again.

-----

1 point by almkglor 5814 days ago | link

Then there's this crazy thing that I haven't actually tested, but which might work:

  (def-all-ss
    #\:  (compose ...)
    ~    (complement R)
    ~    no
    =    (annotate 'mac (fn (_) `(= L ,_)))
    #\.  (...)
    !    (L 'r))
Instead of:

  (if hd
      (= tl (= (cdr tl) (cons o nil)))
      (= hd (= tl       (cons o nil))))
use:

  (if hd
      (tl=:cdr.tl= (cons o nil))
      (hd=:tl=     (cons o nil)))
(untested, of course ^^)

-----

1 point by eds 5814 days ago | link

Something like ->foo would be nice. Even if it didn't have that exact syntax, I use 'coerce enough that it would make a (noticeable albeit small) difference in my code. And I think it is more readable than looking at lots of nested type checks.

Are different ssyntaxes be combinable? Could you, for example,

  (if (int?//num? n)
      ; its a number...
      ; not a number...
Do these ssyntaxes currently get optimized away at compile time (i.e. like 'compose does)? Or do they incur a run-time penalty of some sort?

-----

2 points by almkglor 5814 days ago | link

> Are different ssyntaxes be combinable?

With proper ordering of the ssyntaxes in 'def-all-ss, yes.

> Do these ssyntaxes currently get optimized away at compile time (i.e. like 'compose does)? Or do they incur a run-time penalty of some sort?

Not yet. The run time penalty should be as small as a function-composition overhead. The optimization away of 'compose is done by the Scheme-side 'ac, so if optimizations for 'orf and 'andf and similar are desired, munging them in the scheme-side is necessary.

Edit: As an aside, the above ssyntaxes are not yet implemented in the ssyntaxes.arc file. For the most popular ones - postfix ?, as well as 'andf && and 'orf //, you can modify:

    (def-all-ss
      //   (orf ...)
      &&   (andf ...)
      #\:  (compose ...)
      ~    (complement R)
      ~    no
      #\.  (...)
      !    (L 'r)
      ?    [isa _ 'L])
then you can explore away ^^

-----

1 point by almkglor 5814 days ago | link

Okay, it appears stable now.

As an aside, you just have to (load "ssyntaxes.arc") in the repl, but as I mentioned for some reason it breaks the exit-on-eof feature.

-----

2 points by absz 5814 days ago | link

I've been playing with this, and the other downside is that it's slow. Things are noticeably slower to load (not to run), as the ssyntax check is (a) more complex, and (b) written in Arc, not mzscheme. Other than those two things, though, it's absolutely great.

-----

3 points by almkglor 5814 days ago | link

Might need to use this algo: http://en.wikipedia.org/wiki/Aho-Corasick_algorithm

-----

1 point by absz 5810 days ago | link

Hmm. After looking at that, as far as I can tell it can only match a word which ends in one of the strings in its dictionary. Using it to parse out middle bits would be tricky--you could try saving the string at each accept state, or something like that.

-----

2 points by offby1 5814 days ago | link

Sanctified! Can I get an "amen"?

-----