Arc Forumnew | comments | leaders | submitlogin
Comment tokens
1 point by akkartik 4312 days ago | 4 comments
http://github.com/akkartik/wart/commit/c2e6d0c6d3

Unlike ';', which skips everything until a newline, a ':' skips just itself.

What do y'all think of this idea? Does it pop up any weird interactions?

I'm not sure ':' is the right character for this. It has the pleasing symmetry that these are now always equivalent.

  (f a b c :d d)

  (f : a : b : c :d d)
Credits: David Wheeler and almkglor on readable-discuss (http://sourceforge.net/mailarchive/message.php?msg_id=29539336)


2 points by rocketnia 4312 days ago | link

At first I thought you were saying ":d" was the comment, which struck me as a clever way to make code with confusing positional args more readable without complicating the semantics. I thought maybe you were moving away from keyword args. ;)

But really it's ":" by itself that's a comment. If the reader would read a ":" symbol, instead it ignores that symbol, and there are some idiosyncratic interactions with semantic whitespace. We could duplicate this technique in Racket by sprinkling "#;:" around our code, but ":" is less clutter.

If the only point is to have intentional clutter but not a lot of clutter... then I don't get it. Does the interaction with semantic whitespace actually play a crucial role here?

-----

1 point by akkartik 4312 days ago | link

No, I think this idea works even in a traditional lisp without indent-sensitivity. The problem is that lisps have an if or cond form that interleaves expressions with very different semantics. Lots of other forms have multiple kinds of expressions, but usually the first expression is of one type (bindings) from the rest, or something like that. cond is special because it continues to alternate semantics all the way down, and as the individual expressions grow complex it gets hairy to read. I think judicious use of colons in this manner make if/cond more readable. Especially to non-lispers.

I deliberately chose the example in the commit message to be fully-parenthesized. It's taken from news.arc, and I was trying to show that the colons help distinguish tests and branches. Was that not helpful?

-----

2 points by rocketnia 4311 days ago | link

Ah, I didn't realize you disabled indent-sensitivity inside of parens, so I thought that example's indentation might have been important.

You could be onto something with ":". What do you think of these styles? ^_^

(Sorry for the huge examples.)

  (if : !user
    (submit-login-warning url title showtext text)
      : (~and (or blank.url valid-url.url) ~blank.title)
    (submit-page user url title showtext text retry*)
      : (len> title title-limit*)
    (submit-page user url title showtext text toolong*)
      : (and blank.url blank.text)
    (let dummy 34
      (submit-page user url title showtext text bothblank*))
      : (let site sitename.url
          (or big-spamsites*.site recent-spam.site))
    (msgpage user spammage*)
      : (oversubmitting user ip 'story url)
    (msgpage user toofast*)
    (let s (create-story url process-title.title text user ip)
      (story-ban-test user s ip url)
      (when ignored.user (kill s 'ignored))
      (submit-item user s)
      (maybe-ban-ip s)
      "newest"))

  (if !user
    (submit-login-warning url title showtext text)
  :   (~and (or blank.url valid-url.url) ~blank.title)
    (submit-page user url title showtext text retry*)
  :   (len> title title-limit*)
    (submit-page user url title showtext text toolong*)
  :   (and blank.url blank.text)
    (let dummy 34
      (submit-page user url title showtext text bothblank*))
  :   (let site sitename.url
        (or big-spamsites*.site recent-spam.site))
    (msgpage user spammage*)
  :   (oversubmitting user ip 'story url)
    (msgpage user toofast*)
    (let s (create-story url process-title.title text user ip)
      (story-ban-test user s ip url)
      (when ignored.user (kill s 'ignored))
      (submit-item user s)
      (maybe-ban-ip s)
      "newest"))
When I was working on Penknife, I designed every "if" macro to insert parentheses for its else clause. Mainly I did this so I could put different kinds of conditionals like 'if and 'iflet together in what looked like a single branch, but I liked its effect on self-documentation, which is similar to the use of your ":":

  (if !user
    (submit-login-warning url title showtext text)
   if (~and (or blank.url valid-url.url) ~blank.title)
    (submit-page user url title showtext text retry*)
   if (len> title title-limit*)
    (submit-page user url title showtext text toolong*)
   if (and blank.url blank.text)
    (let dummy 34
      (submit-page user url title showtext text bothblank*))
   if (let site sitename.url
        (or big-spamsites*.site recent-spam.site))
    (msgpage user spammage*)
   if (oversubmitting user ip 'story url)
    (msgpage user toofast*)
   let s (create-story url process-title.title text user ip)
    (story-ban-test user s ip url)
    (when ignored.user (kill s 'ignored))
    (submit-item user s)
    (maybe-ban-ip s)
    "newest")
Nowadays I like the idea of implementing Arc's (a:b ...) ==> (a (b ...)) syntax in the reader, and that would make my Penknife design pattern unnecessary:

  (if !user
    (submit-login-warning url title showtext text)
  :if (~and (or blank.url valid-url.url) ~blank.title)
    (submit-page user url title showtext text retry*)
  :if (len> title title-limit*)
    (submit-page user url title showtext text toolong*)
  :if (and blank.url blank.text)
    (let dummy 34
      (submit-page user url title showtext text bothblank*))
  :if (let site sitename.url
        (or big-spamsites*.site recent-spam.site))
    (msgpage user spammage*)
  :if (oversubmitting user ip 'story url)
    (msgpage user toofast*)
  :let s (create-story url process-title.title text user ip)
    (story-ban-test user s ip url)
    (when ignored.user (kill s 'ignored))
    (submit-item user s)
    (maybe-ban-ip s)
    "newest")
This particular style really would conflict with your keyword arg syntax, and I don't expect it to work in unparenthesized expressions, but maybe you can get something out of it anyway.

-----

1 point by akkartik 4311 days ago | link

Thanks for those examples! Yes, I didn't want to hardcode ':' for just this one cond use case I had in mind. I wanted to let people highlight the tests rather than the branches if they preferred.

One nit: I wish the first two gave branches more indent than tests; I think I'm comparing them to switch statements.

In this fragment from example 1:

    (let dummy 34
      (submit-page user url title showtext text bothblank*))
      : (let site sitename.url
          (or big-spamsites*.site recent-spam.site))
..and in this one from example 2:

    (let dummy 34
      (submit-page user url title showtext text bothblank*))
  :   (let site sitename.url
        (or big-spamsites*.site recent-spam.site))
..the colon isn't separating the cases clearly enough IMO. There's a confounding vertical alignment that distracts the eye.

The discussion on readable-discuss suggested example 2, but it would require editor support to ensure indenting a line doesn't move the ':' at the start. Autoindent settings would also interfere. But they're like #ifdef's, so there's some precedent for doing things this way. Keeping the ':' in column 1 would eliminate the need for clarifying that the colon "does affect the indentation of a line.." That might make them more intuitive.

I hadn't considered the latter two ideas; they are very compelling indeed. I'm going to think about them more.

Ah, I didn't realize you disabled indent-sensitivity inside of parens, so I thought that example's indentation might have been important."

Actually even that is irrelevant ^_^. Even before I disabled indent inside parens those examples wouldn't insert parens anywhere because the inner clauses are all fully parenthesized. Wart has never wrapped a line in parens if it already began with parens.

Basically paren insertion is extremely conservative and avoids messing with code as much as possible. Now that I've disabled it inside parens this is even more true.

-----