On Sat, Jul 14, 2012 at 2:00 AM, David A. Wheeler <dwhee...@dwheeler.com> wrote:
> Kartik Agaram:
>> I just found out about this list (thanks Alan!) and am going to go
>> read through the archives. In the meanwhile I wanted to share the
>> whitespace-sensitive lisp I've been working on. You can read about the
>> design choices I made at:
>>   http://github.com/akkartik/wart#readme
>> I'd love feedback and reactions, whether it's something that makes you
>> go "yuck!" or something unclear in the description.
>
> Thanks for the pointer, I really appreciate it!
>
> Kartik: We'd really appreciate it if you'd participate with us!!   In 
> particular, we're trying to nail down a revision of the spec by July 31, so 
> we'd like to hear what you think.
>
> It's important to note a key difference between wart and readable: 'wart' is 
> a *specific* Lisp-like language and implementation.  In contrast, the 
> "readable" group is trying to develop a *general* notation that can be picked 
> up by many Lisp-like languages.  That said, we want to look at as many ideas 
> as possible now; people can come up with different conclusions, but at 
> *considering* alternatives is important.  And we hope that people will pick 
> up our ideas - including wart.
>
> Quick summary & commentary: Wart has similar indentation rules, though not 
> quite identical (I think our rules are better, see below).  It also appears 
> that f(x) == (f x) in wart, though that's not clear (I infer that from some 
> examples).  Wart lacks curly-infix, which I think is a weakness in wart, but 
> I see no reason why wart can't easily add that. Wart uses ENTER ENTER to end 
> an interactive expression, just like we do. Wart has no equivalent to SPLIT.  
> Wart also has many other abbreviations; abbreviations can be really valuable, 
> but I don't think the wart ones should be added to the "readable" spec.
>
> === DETAILS ===
>
> The initial wart code sample is (prefixing with "." so everyone can see the 
> indentation):
> . def fact(n)
> .     if (iso n 0)
> .       1
> .       (* n (fact (- n 1)))
>
> This is similar to our current "readable" notation, in fact, this is a valid 
> sweet-expression as well.  If we wrote this code using the current draft 
> "readable" notation, we would probably write it like this instead:
> . def fact(n)
> .     if iso(n 0)
> .       1
> .       {n * fact{n - 1}}
>
>
> A key is that "Wart is indentation sensitive. Multi-word lines without 
> leading parens are
> implicitly grouped with later indented lines".  It seems to be basically the 
> same as our indentation rule (and the SFRI too).  Its text says "Lines with a 
> leading paren are never wrapped in parens" - if I interpret that to mean 
> "one-datum lines" I think it *is* the same.
>
> In Wart, indentation process still goes on EVEN INSIDE parens.  I think 
> that's a mistake; indeed, the docs show an example of where this happens & 
> notes that it'd be unexpected.  You can disable indentation processing inside 
> (...): for "wrapping long lists to a new line, you must indent by exactly one 
> space".  Having a way to wrap long lists is nice enough (though our current 
> semantic can do it with parens).
>
> It doesn't seem to be clearly documented, but it appears from examples that 
> wart accepts f(x) as equivalent to (f x), just like our modern-expressions.  
> Which is nice, it's also confirming that others think that makes sense.  
> There is *NO* capability in wart like  curly-infix, or any other capability 
> for infix lists / infix notation.  That said, it would probably trivial to 
> add curly-infix to wart.
>
> "Wart uses a few simple syntax rules to reduce parens further:" and it lists:
> .  a.b ; => (a b) unless a and b are all digits; 2.4 is a number
> .  a.  ; => (a)
>
> I don't see these as particularly helpful.
>
> The first case can already be expressed with (a b) and a(b), which are not 
> particularly longer than "a.b".
> The second case doesn't seem to be much better than (a) or a(), both of which 
> seems clear and short enough.
>
> .  a!b ; => (a 'b)
>
> This is kind of interesting, but it can already be noted as (a 'b) or a('b), 
> and it's not clear to me that this abbreviation is worth it for arbitrary 
> Lisp-based systems.

Ah.  This is a common idiom in Arc.  In Arc, tables can be applied,
and applying a table to a single argument is equivalent to looking up
the key in the table.  Thus, when doing objects in Arc, you use a
table, set up keys, and us a!b syntax.  Something like:

let
  \ obj
  \ \ table
        'key1 \ val1
        'key2 \ fn (x) {x + 42}
  obj!key2 obj!key1

Thus, at least in Arc, a!b syntax is considered useful.

a.b stems out of a!b syntax.  Consider a.'b.  Now pretend to squish
them together so that the ' lies over the . so you get a!b .  So Arc
says (a b) can be expressed as a.b and that (a 'b) can be expressed as
a!b.

>
> .  !a  ; => (not a)
>
> This looks like Arc, though Arc uses ~.
>
> .  f:g ; => (compose f g)
>
> I'm not sure this is worth a special abbreviation.

Again, an Arc-ism.  Inside Arc's secret deep layers, something like this:

 (foo:bar:nitz:quux a)

gets converted, NOT to compose, but instead to:

 (foo (bar (nitz (quux a))))

This is important: compose does *not* work with macros, but (foo:bar
nitz) works properly if foo is a macro - foo sees (foo (bar nitz)).

So saying f:g => (compose f g) isn't 100% accurate, because : syntax
is handled extra-specially at the head of a list.

>
> .  f&g ; => (andf f g)
>
> Again, not sure this worth an abbreviation.  Of course, "and" appears often, 
> but I think our curly-infix approach is more readable & more general: {f and 
> g}. I notice that the wart notation doesn't support "or" (!).

andf is slightly different - it's NOT and.  andf is a higher-order function:

def andf(f g)
  fn (x)
    {f(x) and g(x)}

So, f&g is useful as a function:

; instead of: {f(a) and g(a)}
f&g(a)



>
> .  ~f  ; => (complement f)
>
> Uses Arc's symbol/notation, but for a slightly different semantic.
>

I think I might not have been very clear about ~ in arc.  ~f in Arc
has always been (complement f).  So ~f(x) is slightly different from
~(f()).

>
> I can sort-of see the point of a special notation for "not"; Arc does that 
> too.  But the modern-expression approach actually works pretty well:
> ~(f()) => (~ (f))
> !(f()) => (! (f))
> not(f()) => (not (f))
>
> Wart's interpreter says "Hit <enter> twice to eval."
> which is our current semantic, too.  Good to see that other people come to 
> similar conclusions as we do.


Sincerely,
AmkG

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Readable-discuss mailing list
Readable-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/readable-discuss

Reply via email to