readable-discuss Mailing List for Readable Lisp S-expressions
Readable Lisp/S-expressions with infix, functions, and indentation
Brought to you by:
dwheeler
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
(1) |
Aug
|
Sep
|
Oct
(3) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
(19) |
Dec
(27) |
2008 |
Jan
(38) |
Feb
(13) |
Mar
(2) |
Apr
|
May
(2) |
Jun
|
Jul
(4) |
Aug
|
Sep
|
Oct
|
Nov
(19) |
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(4) |
Jun
(11) |
Jul
(440) |
Aug
(198) |
Sep
(30) |
Oct
(5) |
Nov
(6) |
Dec
(39) |
2013 |
Jan
(162) |
Feb
(101) |
Mar
(39) |
Apr
(45) |
May
(22) |
Jun
(6) |
Jul
(12) |
Aug
(17) |
Sep
(23) |
Oct
(11) |
Nov
(77) |
Dec
(11) |
2014 |
Jan
(4) |
Feb
(5) |
Mar
|
Apr
|
May
(20) |
Jun
(24) |
Jul
(14) |
Aug
|
Sep
(1) |
Oct
(23) |
Nov
(28) |
Dec
(5) |
2015 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(18) |
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
(6) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
(2) |
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2020 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2022 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Damien M. <dam...@gm...> - 2022-03-26 22:47:19
|
it seems it does not work with Guile 3.0 ? |
From: Martin N. <mar...@gm...> - 2021-05-15 11:55:25
|
I have added to Reddit r/whitespaceLisp a link to the project Readable. |
From: Alberto A. <alb...@gm...> - 2020-04-13 01:42:32
|
Hello, I love the project! However, enabling sweet-expressions has caused some issues. Namely, I cannot insert #\#. It gives some weird error, please see what's wrong. I'm using SBCL2.0.3 + SLIME + emacs 27. And by the way, have you considered moving to github? It's easier to have people post questions etc. Kind regards and awesome stuff! Thank you, Alberto |
From: Jéssica M. <jes...@gm...> - 2019-07-09 02:51:02
|
I'm not sure if anyone is still maintaining this project. I just tried to install it with `(ql:quickload :readable)` is not working. Jéssica |
From: Arne B. <arn...@we...> - 2017-12-13 17:48:35
|
Hi Alan, Thank you for your answer! Alan Manuel Gloria <alm...@gm...> writes: > This is arguably NOT a Guile-specific issue, but rather a general issue. > Clojure uses its array syntax for parts of its syntax, for example. > > The ## seems OK, but how about just plain # ? That’s part of why it’s Guile specific: I cannot use the plain #, because that’s the prefix for symbols and illegal syntax for read. I don’t see a way to do this as simple reader addition. > So like (using only (read) and not (eval (read))): > > ' a b > => (quote (a b)) > '(a b) > => (quote (a b)) > # a b > => #(a b) > #(a b) > => #(a b) I’d like to do it that way, but from what I can tell, doing that would mean that I have to special-case all special syntax reading, while with the ## I can harness regular symbol reading in Guile. The # is the prefix for all kinds of special elements (i.e. #' #, #,@) and I’m not sure it’s a good idea to take the symbol itself for a given feature. Best wishes, Arne -- Unpolitisch sein heißt politisch sein ohne es zu merken |
From: Alan M. G. <alm...@gm...> - 2017-12-12 22:58:34
|
This is arguably NOT a Guile-specific issue, but rather a general issue. Clojure uses its array syntax for parts of its syntax, for example. The ## seems OK, but how about just plain # ? So like (using only (read) and not (eval (read))): ' a b => (quote (a b)) '(a b) => (quote (a b)) # a b => #(a b) #(a b) => #(a b) Sincerely, AmkG On Mon, Nov 13, 2017 at 6:38 AM, Arne Babenhauserheide <arn...@we...> wrote: > > Matt Wette <mat...@gm...> writes: > > > Do you have a syntax for vector literals? If not, why can't you just > write > > I don’t, but while > > (vector '(a b)) > ⇒ #((a b)) > > (define (f) > (vector '(a b)) #f) > (procedure-properties f) > ⇒ ((name . f)) > > But > (define (f) > #((a b)) #f) > (procedure-properties f) > ⇒ ((name . f) (a b)) > > So this is a purely Guile-specific issue: I want Guile to recognize the > vector as function-property. If it recognized (vector ...), I could use > the simple syntax > > define : hello who > . "Say hello to WHO" > vector > ' tests > test-equal "Hello World!\n" > hello "World" > format #f "Hello ~a!\n" > . who > > (this would be my preferred approach, but I did not find any way to get > this working) > > Best wishes, > Arne > -- > Unpolitisch sein > heißt politisch sein > ohne es zu merken > > ------------------------------------------------------------ > ------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Readable-discuss mailing list > Rea...@li... > https://lists.sourceforge.net/lists/listinfo/readable-discuss > > |
From: Arne B. <arn...@we...> - 2017-11-12 22:50:10
|
Matt Wette <mat...@gm...> writes: > Do you have a syntax for vector literals? If not, why can't you just write I don’t, but while (vector '(a b)) ⇒ #((a b)) (define (f) (vector '(a b)) #f) (procedure-properties f) ⇒ ((name . f)) But (define (f) #((a b)) #f) (procedure-properties f) ⇒ ((name . f) (a b)) So this is a purely Guile-specific issue: I want Guile to recognize the vector as function-property. If it recognized (vector ...), I could use the simple syntax define : hello who . "Say hello to WHO" vector ' tests test-equal "Hello World!\n" hello "World" format #f "Hello ~a!\n" . who (this would be my preferred approach, but I did not find any way to get this working) Best wishes, Arne -- Unpolitisch sein heißt politisch sein ohne es zu merken |
From: Arne B. <arn...@we...> - 2017-11-12 20:32:07
|
Hi, Wisp¹ as general syntax is pretty much done. The releases this year only provided bug fixes and additional examples. A procedure definition looks like this: define : hello who format #f "Hello ~a!\n" . who From experience with building tools with Wisp² I am pretty happy with its syntax; it feels like a sweet spot between minimal syntax-overhead and producing easily readable code (leaning a bit more towards minimal syntax-overhead than readable/sweet). But there is one Guile-specific feature where it is lacking: When defining a procedure in Guile, you can add properties by creating a literal array as line — or as second line if the first line is a literal string that then serves as documentation. This can be used to define tests.³ Then a full fledged Hello World! looks like this: define : hello who . "Say hello to WHO" . #((tests (test-equal "Hello World!\n" (hello "World")))) format #f "Hello ~a!\n" . who And this is all and nice, but it prevents using indentation-based syntax for the properties. This would be no problem if I could simply make an array with non-literal syntax — i.e. (list->array (list (list tests (list test-eqv ...)))) — but Guile property syntax requires a literal array. Therefore I created a reader-extension⁴ which allows creating literal arrays with indentation-based syntax using the hash-extension ##: define : hello who . "Say hello to WHO" ## tests test-equal "Hello World!\n" hello "World" format #f "Hello ~a!\n" . who To my eyes this looks reasonably nice, and it allows using arbitrary arrays. It uses the conventional #-extension common to Scheme which avoids adding more constructs, and internally it just passes ## a b c to the wisp paren-restructuring code as (#\# a b c) which then becomes #(a b c) as used in similar fashion for the other special paren-prefixes ("'" "," "#'", ...). But it feels strange to add specialized syntax here. I would rather want something more general — something which does not feel like opening a can of worms of more and more syntax elements which could crop in. It feels like straying from the path of simplicity. Therefore I’d like to ask you for comments. Do you have ideas how this could be made more elegant? Or is this intrinsic complexity of the Scheme or Guile literal array prefix (and the other paren-prefixes) which I cannot escape with wisp? Best wishes, Arne ¹: Wisp website: http://www.draketo.de/english/wisp ²: Wisp examples (tools with wisp): https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/examples/ ³: This doctest syntax is built on SRFI-64 and implemented in <https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/examples/doctests.w> and <https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/examples/doctests.scm> ⁴: The code for the reader extension consists of a single line in the reader: read-hash-extend #\# : λ (chr port) #\# <https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/wisp-reader.w#wisp-reader.w-39> eight lines in the clean parser (currently mostly a hack) <https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/wisp-scheme.w#wisp-scheme.w-689> and some special cases in the bootstrap parser and wisp->lisp converter which operates on bare strings <https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/wisp-guile.w#wisp-guile.w-513> <https://bitbucket.org/ArneBab/wisp/src/e80659fcc896ab04fbcd0a2d78e0dc25fef474a0/wisp-guile.w#wisp-guile.w-567> -- Unpolitisch sein heißt politisch sein ohne es zu merken |
From: Alan M. G. <alm...@gm...> - 2017-02-28 16:04:37
|
Re: "Usage:" comment, I suppose the text editor would have to correctly parse the below? (define-syntax simple-define-syntax ; Usage: (simple-define-syntax (<macro> <template> ...) <expansion>) (syntax-rules () ((simple-define-syntax (<macro> <template> ...) <expansion>) (define-syntax <macro> (syntax-rules () ((<macro> <template> ...) <expansion>)))))) (simple-define-syntax (delay #| Usage: (delay <expression>) - Delay execution of <expression>|# <expression>) (delay-force (make-promise <expression>))) (simple-define-syntax (define-stream ; Usage: (define-stream (<func> <args> ...) <body> ...) - define a function that returns a stream, and may tail-call a function that returns a stream (<func> <args> ....) <body> ...) (define <func> (stream-lambda (<args> ...) <body> ...))) ....or, I don't know, can you be more precise about the rules for where the Usage: comment is placed? Given a ; Usage: comment, where does it get attached in the text form of the program? Lisps allow new definitional forms, which themselves may have a different syntax for indicating the symbol that is to be defined. That said, a good rule for where a ;Usage: comment ought to go might possibly be definable. Sincerely, AmkG On Tue, Feb 21, 2017 at 10:49 AM, luke wallace <luk...@gm...> wrote: > I went to great pains to explain that what symbols mean would have to be > explained by the symbol/function creator in a comment inside the > symbol/function definition. The editor would pull the explanation from that > comment. The comment would have some identifier, such as "Usage:" or > "Tooltip:" to prefix the comment, so that the editor knew it was a special > comment. Each function/symbol would have to be manually commented in this > way before the editor knew about it - after all, we can't expect an editor > to speak to humans in an understandable way about what a function does > without telling it so - because if it could we probably wouldn't need human > programmers any more. > |
From: luke w. <luk...@gm...> - 2017-02-21 02:49:37
|
I went to great pains to explain that what symbols mean would have to be explained by the symbol/function creator in a comment inside the symbol/function definition. The editor would pull the explanation from that comment. The comment would have some identifier, such as "Usage:" or "Tooltip:" to prefix the comment, so that the editor knew it was a special comment. Each function/symbol would have to be manually commented in this way before the editor knew about it - after all, we can't expect an editor to speak to humans in an understandable way about what a function does without telling it so - because if it could we probably wouldn't need human programmers any more. I've been doing a lot of research on this and I hit a jackpot of information. What I'm basically describing and edging towards is called a projectional editor. Jetbrains MPS is probably the most advanced projectional editor out there, which does not need a parser, because it directly manipulates the AST (abstract syntax tree). It displays the code in a number of views - the 2 minute video is worth more than a thousand words: https://www.youtube.com/watch?v=XolJx4GfMmg Jetbrains MPS appears to be an extremely complex piece of software, the interface, while functional, is about as complicated as an airplane cockpit, and I'm just not a fan of that kind of thing. Programming should be simple and elegant like lisp, even within a projectional editor. I suspect there's a better way to make a projectional editor by building the abstract syntax tree using s-expressions, which would make it easier and simpler to implement DSL's while keeping the end-result pretty, but this is just a hunch, more research is required.. |
From: David A. W. <dwh...@dw...> - 2017-02-21 02:27:26
|
On Mon, 20 Feb 2017 15:36:22 -0600, luke wallace <luk...@gm...> wrote: > Here's a similar but slightly different prototype > > https://i.imgur.com/vApN1Yt.png Quick nitpick - please use these terms: () - parentheses [] - (square) brackets {} - (curly) braces I realize that some people call *all* of the paired characters "brackets", but since we have to talk about paired characters often around here, it's helpful to be very precise about these terms :-). > This prototype uses a flatter version of tables, and much more 'magic' > would have to be programmed into the editor > cells shaded grey are prefix-comments, in this case, for the function > 'define'. There are bit minuses to this. This assumes that the editor "knows" what terms like 'define' and '<=' and 'if' mean. I imagine there are some uses for it, primarily if you use Lisp exactly the same way as you'd use a fixed-syntax language like Java. But fixed-syntax languages are going to be much better at being themselves than a Lisp ever could. If you need a fixed-syntax language, there are over a hundred of them. A key advantage to Lisp is that you can embed many different languages & can trivially create your own. Mini-languages abound! There's no particular reason that "<=" or "define" would have the same meaning each time even within one line, and there's no way an editor could determine the meaning in general (it would have to recursively expand macros across all files, and even then, there's no mechanism for capturing this information in general). That said, *displaying* boxes is a good idea. I think it's been done before, but it's fair to point out that modern systems make this *much* easier and more practical. And you don't need *any* magic to display the boxes. So, when will you be implementing a prototype :-) ? --- David A. Wheeler |
From: luke w. <luk...@gm...> - 2017-02-20 21:36:33
|
Here's a similar but slightly different prototype https://i.imgur.com/vApN1Yt.png This prototype uses a flatter version of tables, and much more 'magic' would have to be programmed into the editor cells shaded grey are prefix-comments, in this case, for the function 'define'. prefix-comments would have to be set up for each function for a given language/variant, but would enable a form-filling experience resulting in lisp code - and most near computer illiterates wouldn't mind coding if it was mostly filling in forms. cells with bold text are contextual-comments - the usage comment is contextual to the 'factorial' function, and the 'then' and 'else' comments are contextual to the 'if' function. these are set up for each function for a given language/variant, just like prefix-comments. The 'define' cell spans the whole table - therefore everything under it is wrapped in its parens The next part relies on a bit of magic, 'factorial' starts an open paren, but does not close unless the 'Parameter(s)' box is left empty. If the parameter(s) block is left empty, factorial will be a function without arguments and close paren. The editor would have to handle these conditions for the 'define' symbol (or any symbol used to create functions). The 'usage' prefix-comment and its corresponding contextual-comment are used for the tooltip in the editor wherever the function is used (including in the definition code of this recursive function), and also as a readable snippet when someone looks at the function definition, to understand what it does. This might help libraries of functions be more understandable in the long run, as they would be self documenting not just in how to use them, but where and why to use them. The 'code' prefix-comment uses special logic to open/close parens. The first piece of actual code, the 'if' opens a parens and does not close until a new symbol in the same column exists. Since 'then' and 'else' are not symbols, but are comments, it doesn't close until the end of the table (before the 'define' ends though). 'n <= 1' opens, then closes because '1' is on the same column, and is actual code '1' opens, then closes because 'n*' is on the same column, and is actual code 'n* opens, then 'factorial' opens, then 'n-1' opens, from left to right, and they all close at the end of the table, but before the 'if'. The goal of doing it this way is to prevent excessive nesting of cells - and use implied nesting through the logic of columns. On Mon, Feb 20, 2017 at 1:03 PM, David A. Wheeler <dwh...@dw...> wrote: > On Mon, 20 Feb 2017 11:47:35 -0600, luke wallace < > luk...@gm...> wrote: > > Here is my new idea for an ideal lisp authoring format, which relies on > an > > html/css/js editor using pretty components around source lisp code. > Source > > lisp code is still saved as a text file, but is, upon loading into this > > theoretical editor, "pretty formatted" as shown in the image below. > > Very interesting. Even if it's not used for editing, I can imagine > something > like this as the output of a pretty-printing process. > > I wonder about *editing* while doing this, though. > Perhaps entering "(" would automatically add a closing ")", > show the box (if not preceded by whitespace), and move the user inside. > > > Inside this editor, creating parentheses in the right context would > instead > > create nested table cells as shown in the image. Instead of working with > > parentheses, newbies might find it easier to look at tables like this... > > Newbies don't stay newbies. I'd like to think that any "readable Lisp" > would be just as useful to experts as to newbies. Experts have to read > a lot of code... making their lives easier is a good idea too :-). > > > Using more html/css/js magic, it would be possible in such an editor to > do > > things like display a tooltip when a user hovered over recognized symbols > > such as <= in the image. The tooltip could display an explanatory message > > like "less than or equal to". While experienced programmers may not need > > the <= symbol explained to them, by explaining every symbol, it should > > become even more readable in the editor. > > One challenge is that "<=" doesn't have a fixed meaning; it might mean the > underlying Lisp implementation, or the meaning of "<=" as redefined in > some other language you're defining there. > > > In this prototype image, the parentheses are shown as square table cells, > > but they could be rounded, given line width, background colors, or change > > colors on mouse-hover, keyboard focus, or when using a debugger to step > > through code line by line (indicating what portion of the table is being > > evaluated) etc. The possibilities are endless if we step out of the > > shackles of needing to see source code as the language dictates it. > > Sure. You need to be cafeful, though; bugs are easy to hide if the > developer > can't easily "see" what the code actually *is*. I think experimentation > would > be necessary. > > This probably wouldn't be too hard to prototype in an editor - I'd love to > hear > if you give it a try. > > --- David A. Wheeler > |
From: David A. W. <dwh...@dw...> - 2017-02-20 19:42:00
|
On Mon, 20 Feb 2017 11:47:35 -0600, luke wallace <luk...@gm...> wrote: > Here is my new idea for an ideal lisp authoring format, which relies on an > html/css/js editor using pretty components around source lisp code. Source > lisp code is still saved as a text file, but is, upon loading into this > theoretical editor, "pretty formatted" as shown in the image below. Very interesting. Even if it's not used for editing, I can imagine something like this as the output of a pretty-printing process. I wonder about *editing* while doing this, though. Perhaps entering "(" would automatically add a closing ")", show the box (if not preceded by whitespace), and move the user inside. > Inside this editor, creating parentheses in the right context would instead > create nested table cells as shown in the image. Instead of working with > parentheses, newbies might find it easier to look at tables like this... Newbies don't stay newbies. I'd like to think that any "readable Lisp" would be just as useful to experts as to newbies. Experts have to read a lot of code... making their lives easier is a good idea too :-). > Using more html/css/js magic, it would be possible in such an editor to do > things like display a tooltip when a user hovered over recognized symbols > such as <= in the image. The tooltip could display an explanatory message > like "less than or equal to". While experienced programmers may not need > the <= symbol explained to them, by explaining every symbol, it should > become even more readable in the editor. One challenge is that "<=" doesn't have a fixed meaning; it might mean the underlying Lisp implementation, or the meaning of "<=" as redefined in some other language you're defining there. > In this prototype image, the parentheses are shown as square table cells, > but they could be rounded, given line width, background colors, or change > colors on mouse-hover, keyboard focus, or when using a debugger to step > through code line by line (indicating what portion of the table is being > evaluated) etc. The possibilities are endless if we step out of the > shackles of needing to see source code as the language dictates it. Sure. You need to be cafeful, though; bugs are easy to hide if the developer can't easily "see" what the code actually *is*. I think experimentation would be necessary. This probably wouldn't be too hard to prototype in an editor - I'd love to hear if you give it a try. --- David A. Wheeler |
From: luke w. <luk...@gm...> - 2017-02-20 17:47:44
|
Here is my new idea for an ideal lisp authoring format, which relies on an html/css/js editor using pretty components around source lisp code. Source lisp code is still saved as a text file, but is, upon loading into this theoretical editor, "pretty formatted" as shown in the image below. Inside this editor, creating parentheses in the right context would instead create nested table cells as shown in the image. Instead of working with parentheses, newbies might find it easier to look at tables like this, which show the nested structure more visually. The example image uses the factorial function from the readable website homepage. There is an extra column with text in bold which are comments. Comments in this manner can be put anywhere, and will always be bold so they are easily distinguished. This allows newbies to document their code, or an editor to document their code for them, for functions like "if" that the theoretical editor knows about. Also, the "define" function is the parent function for this block, so it has its text centered - an easy visual way to distinguish the parent besides just the outer border. Comments could be disabled by a menu option in the editor. Specifically, these special comments which are generated by the editor could be hidden at the users request, while keeping different types of comments from the source file visible in some way. So far, this just shows infix notation (taken from readable lisp) and a new way to represent parentheses and comments/dynamic comments. https://i.imgur.com/Q9lpfVa.png Using more html/css/js magic, it would be possible in such an editor to do things like display a tooltip when a user hovered over recognized symbols such as <= in the image. The tooltip could display an explanatory message like "less than or equal to". While experienced programmers may not need the <= symbol explained to them, by explaining every symbol, it should become even more readable in the editor. In this prototype image, the parentheses are shown as square table cells, but they could be rounded, given line width, background colors, or change colors on mouse-hover, keyboard focus, or when using a debugger to step through code line by line (indicating what portion of the table is being evaluated) etc. The possibilities are endless if we step out of the shackles of needing to see source code as the language dictates it. |
From: David A. W. <dwh...@dw...> - 2016-09-25 12:42:58
|
>I suppose I could define a function that swaps the first 2 arguments >then >evaluates. In newlisp, this won't cause any slowdown. Curly-infix does a little more than that. Feel free to steal its code, it is under the MIT license. If there are only three arguments, then it does indeed just swapped the first two arguments. However, if there are an odd number of arguments, where the number of arguments are three or more, and the even arguments are all identical, then the one even argument is the front and the rest are the final arguments. This lets you do things like this: {a + b + c + {d * e }} >ColorForth distinguishes between immediate and compiled words > ... be >nice to >have that distinction in Lisp. I've used several Forths and I own the book "Starting Forth". Forth and Lisp are radically different. That said, lisp does have ways to distinguish between actions taken while reading code, macros, and normal code. Scheme does not have a standard way to adjust the readtable (to control what happens while reading an expression) but common lisp does. Common Lisp also has eval-when: http://www.lispworks.com/documentation/lw50/CLHS/Body/s_eval_w.htm I think that controlling infix is much better if handled by the reader in lisp. --- David A.Wheeler |
From: Alan M. G. <alm...@gm...> - 2016-09-21 22:00:55
|
On Thu, Sep 22, 2016 at 4:08 AM, David Walther < da...@cl...> wrote: > On Wed, Sep 21, 2016 at 08:11:09AM -0400, David A. Wheeler wrote: > >Okay. Clojure uses {...} for hashes, so newLisp isn't the only Lisp > where {} > >has another meaning. The question is, how should infix be handled? > >It really needs some paired characters, and (...) are spoken for. > >Does newLisp already assign [...] a meaning? > > newLisp uses [...] for the tag pairs previous mentioned [cmd] and [text], > and > the parser doesn't allow [ to be used as first character of a symbol. > Well, if currently the only place where [...] is allowed used are the tags [cmd], [/cmd], [text], [/text], then I don't see a reason why we can't automatically convert [a + [b * c]] to (+ a (* b c)) at the unsweeten level. (but if you need readable lisp in your parser directly instead of via the unsweeten converter, well, maybe it'll need to get overhauled...) >If so, the best approach may be to use > >«x + 1» : Left/right-pointing double-angle quotation mark, U+AB/U+BB. > These are very well-supported (e.g., they are used for French quotations > and are in Latin-1), and in many cases are the easiest to enter. There is a > risk of them being too similar to the comparison operators < and >, but > this doesn't seem too bad. Nested example: fact«n * «n - 1»» > > > >I discuss this here: > >https://sourceforge.net/p/readable/wiki/Clojure/ > > I suppose I could define a function that swaps the first 2 arguments then > evaluates. In newlisp, this won't cause any slowdown. Then infix would > look > like this (similar to bourne shell [ function) > > > (define-macro (infix a b) (eval (extend (list b a) (args)))) > (lambda-macro (a b) (eval (extend (list b a) (args)))) > > (if (infix 1 = 2) 5 10) > 10 > > (if (infix 1 = 1) 5 10) > 5 > > ColorForth distinguishes between immediate and compiled words... be nice to > have that distinction in Lisp. Then a symbol could behave like this at > compile stage: > > (a = b) => (apply = (a b)) > > (a = b or c > d) => (apply or (apply = (a b)) (apply > (c d))) > > Then we get into C style precedence rules. > > Since infix notation is really useful mostly for mathematical and logical > comparisons, perhaps defining "m" for "math" would have to do the job for > infix. Where "m" is a full interpreter with precedence rules etc. > > (if (m a = b or c > d) e f) > I built an infix macro for Common Lisp before (it's what got me invited on this list). With precedence even. Overall, we've found precedence to be less useful; see https://sourceforge.net/p/readable/wiki/Precedence/ Also, depending on how newlisp handles macros, an infix macro might not be as powerful as you think. Classical motivating example for why we should have infix handled at the reader rather than at the macro level: {a + b} ; add the number a to the number b, yielding a number (map . {a + b}) ; add the list of numbers a to the list of numbers b, yielding a list of numbers. The latter gets translated at the reader level to (map . (+ a b)), equivalent to (map + a b), which fits how map is often used in Lisplikes. If you use an infix macro, (map . (m a + b)), that probably will not work - it's (map m a + b). Even if you can run macros dynamically, consider that typically + will be a function, not a list of functions. SRFI-26 also provides a nice "cut" macro that also works well with reader-level infix: (cut - a <>) ; -> (lambda (<>) (- a <>)), a function that subtracts its argument from a (cut . {a - <>}) ; as above, a function that subtracts its argument from a > > >> Also, newlisp source code is in UTF-8. Is sweeten UTF-8 compatible? > > > >It's *supposed* to be, as long as the underlying Scheme is. It probably > >hasn't been adequately tested that way, but if it's not, it's a bug and > needs > >to be fixed. > > I have some source code I can test it on. UTF-8 lets me use mathematical > symbols like "delta" and "differential" and theta, phi, and pi from high > school > trigonometry > > David > > ------------------------------------------------------------ > ------------------ > _______________________________________________ > Readable-discuss mailing list > Rea...@li... > https://lists.sourceforge.net/lists/listinfo/readable-discuss > |
From: David W. <da...@cl...> - 2016-09-21 20:08:33
|
On Wed, Sep 21, 2016 at 08:11:09AM -0400, David A. Wheeler wrote: >Okay. Clojure uses {...} for hashes, so newLisp isn't the only Lisp where {} >has another meaning. The question is, how should infix be handled? >It really needs some paired characters, and (...) are spoken for. >Does newLisp already assign [...] a meaning? newLisp uses [...] for the tag pairs previous mentioned [cmd] and [text], and the parser doesn't allow [ to be used as first character of a symbol. For dictionaries, newLisp does it like this: (define d:d) ; define d as a dictionary (d a b) ; assigns b to a in dictionary d (d a) ; looks up a in d, returns the value Dictionaries are first class objects in newlisp, but they don't nest. They are all defined and stored at the top level, called MAIN. This is for garbage collection reasons. >If so, the best approach may be to use >«x + 1» : Left/right-pointing double-angle quotation mark, U+AB/U+BB. These are very well-supported (e.g., they are used for French quotations and are in Latin-1), and in many cases are the easiest to enter. There is a risk of them being too similar to the comparison operators < and >, but this doesn't seem too bad. Nested example: fact«n * «n - 1»» > >I discuss this here: >https://sourceforge.net/p/readable/wiki/Clojure/ I suppose I could define a function that swaps the first 2 arguments then evaluates. In newlisp, this won't cause any slowdown. Then infix would look like this (similar to bourne shell [ function) > (define-macro (infix a b) (eval (extend (list b a) (args)))) (lambda-macro (a b) (eval (extend (list b a) (args)))) > (if (infix 1 = 2) 5 10) 10 > (if (infix 1 = 1) 5 10) 5 ColorForth distinguishes between immediate and compiled words... be nice to have that distinction in Lisp. Then a symbol could behave like this at compile stage: (a = b) => (apply = (a b)) (a = b or c > d) => (apply or (apply = (a b)) (apply > (c d))) Then we get into C style precedence rules. Since infix notation is really useful mostly for mathematical and logical comparisons, perhaps defining "m" for "math" would have to do the job for infix. Where "m" is a full interpreter with precedence rules etc. (if (m a = b or c > d) e f) >> Also, newlisp source code is in UTF-8. Is sweeten UTF-8 compatible? > >It's *supposed* to be, as long as the underlying Scheme is. It probably >hasn't been adequately tested that way, but if it's not, it's a bug and needs >to be fixed. I have some source code I can test it on. UTF-8 lets me use mathematical symbols like "delta" and "differential" and theta, phi, and pi from high school trigonometry David |
From: David A. W. <dwh...@dw...> - 2016-09-21 12:11:18
|
On Tue, 20 Sep 2016 13:20:26 -0700, David Walther <da...@cl...> wrote: > Hi, nice work on sweet expressions. Thanks! And thanks for contributing to this mailing list. > Could you add a newlisp mode for sweeten? I'm fine with adding a new mode for sweeten... but I'm kind of hoping that *you* would provide those improvements. But I'd be happy to help you get there. BTW, you probably want to improve "unsweeten", not "sweeten". > The main issue is that the # character in newlisp is treated as "comment until > end of line", and there are no #! (or #|?) style multiline comments. Several things probably need parameters, e.g., the characters for comments to the end of line, and multiline comments are supported. Supporting Clojure has similar issues - there should be a few parameterizations. There's already basic support for a Common Lisp mode. In Common Lisp it's probably better to use the implementation specifically for Common Lisp, but for generic data processing modifying "unsweeten" might be easier. > # has no other special meanings, it isn't a prefix for special data types. Again, this sounds like something needing parameterization. > ; means the same thing as it does in regular LISP. So *both* # and ; begin comments? Interesting. But that's not a big problem. > Also there are a few things from bbcode, like [cmd][/cmd], and [text][/text] > tag pairs. [cmd][/cmd] is only used in interactive mode, but both tag pairs > can be considered as literal multiline strings without escaping. Another parameter, no big deal. > Also, newLisp uses {} to delimit a literal string. I am ok with {} literal > strings being turned into quoted "" strings. newlisp "" strings are escaped > just like C and JavaScript. Okay. Clojure uses {...} for hashes, so newLisp isn't the only Lisp where {} has another meaning. The question is, how should infix be handled? It really needs some paired characters, and (...) are spoken for. Does newLisp already assign [...] a meaning? If so, the best approach may be to use «x + 1» : Left/right-pointing double-angle quotation mark, U+AB/U+BB. These are very well-supported (e.g., they are used for French quotations and are in Latin-1), and in many cases are the easiest to enter. There is a risk of them being too similar to the comparison operators < and >, but this doesn't seem too bad. Nested example: fact«n * «n - 1»» I discuss this here: https://sourceforge.net/p/readable/wiki/Clojure/ > Also, newlisp source code is in UTF-8. Is sweeten UTF-8 compatible? It's *supposed* to be, as long as the underlying Scheme is. It probably hasn't been adequately tested that way, but if it's not, it's a bug and needs to be fixed. --- David A. Wheeler |
From: David W. <da...@cl...> - 2016-09-20 20:47:14
|
Hi, nice work on sweet expressions. Could you add a newlisp mode for sweeten? The main issue is that the # character in newlisp is treated as "comment until end of line", and there are no #! (or #|?) style multiline comments. # has no other special meanings, it isn't a prefix for special data types. ; means the same thing as it does in regular LISP. Also there are a few things from bbcode, like [cmd][/cmd], and [text][/text] tag pairs. [cmd][/cmd] is only used in interactive mode, but both tag pairs can be considered as literal multiline strings without escaping. Also, newLisp uses {} to delimit a literal string. I am ok with {} literal strings being turned into quoted "" strings. newlisp "" strings are escaped just like C and JavaScript. Also, newlisp source code is in UTF-8. Is sweeten UTF-8 compatible? David |
From: Alan M. G. <alm...@gm...> - 2016-09-18 01:46:14
|
Well, backquotes are already used in Haskell to convert prefix symbols to infix, so I decided to reuse backquotes to convert infox symbols to prefix ^^ "let" and "where" syntax is always a problem... data (List a) . `:` :: a -> List a -> List a . Nil :: List a codata (Stream a) . head :: Stream a -> a . tail :: Stream a -> Stream a The main point is really just to implement syntax extensions in a non-Lisp language. ^^ In the 80's Scheme macrologists would discuss a little about using Scheme-style macros in C (!), but in the late 80's and 90's such mentions in the Scheme macro papers grew less and less until they just mention Scheme. Some more examples: codata (Rec a) . stepRec :: Rec a -> Either (Rec a) a instance (Monad Rec) . -- codata types (Rec a) use copatterns . stepRec (return a) = Right a . stepRec (ma >>= fmb) = case (stepRec ma) . . Left ma' -> Left (ma' >>= fmb) . . Right a -> fmb a -- Fix point operator fixRec :: ((a -> Rec b) -> (a -> Rec b)) -> (a -> Rec b) stepRec (fixRec ff a) = value . ff subcall a . where . . stepRec (subcall a') = fixxRec ff a' |
From: David A. W. <dwh...@dw...> - 2016-09-14 00:36:21
|
On September 13, 2016 7:22:55 PM EDT, Alan Manuel Gloria <alm...@gm...> wrote: >On Tue, Sep 13, 2016 at 8:11 AM, David A. Wheeler ><dwh...@dw...> >wrote: > >> >> >4. Backquotes "invert" the use of a symbol: foo is a prefix symbol, >> >`foo` >> >is an infix symbol; while + is an infix symbol while `+` is a prefix >> >symbol. >> >> How will you identify quasi quoting? Or do users simply have to use >the >> full name quasiquote ? >> > >Full name, sadly ^^ > >The target I'm planning for these rules is not, technically speaking, a >Lisp (a dynamically-typed language whose primary data type is used to >represent its code) but rather a Haskell-like language. > >The point of this is to allow a Scheme macro processor to be used on a >Haskell-like language. So, quasiquote is a lot less needed. > >syntax `<-` >syntax do >. transform >. . do >. . . p <- x >. to $ syntaxError "do: last form cannot be `p <- x'" p >. transform >. . do >. . . x >. to >. . x >. transform >. . do >. . . p <- x >. . . y >. . . ... >. to >. . . x >>= \ p -> do y ... >. transform >. . do >. . . x >. . . y >. . . ... >. to >. . x >>= \ _ -> do y ... > >(well, "\" would also have to be prefix-defaulted, and the "function" >syntax would be `->` rather than \ here, with \ being a dummy stand in) > >Still, let (or "where", which is a more common idiom in Haskell-like >languages, although "let" does still exist) is difficult to express in >a >good indentation form.... > >fix :: ((a -> b) -> (a -> b)) -> (a -> b) >map = value >. fix rec >. where >. . rec map f (a:as) = f a:map f as >. . rec map f Nil = Nil >{- >(map = (value > (fix rec) > (where > ((rec map f (a:as)) = ((f a):(map f as))) > ((rec map f NIl) = Nil)))) >-} > >blech! > >Sincerely, >AmkG I don't know if it would help your use case, but you could use vertical bars to surround symbols that you don't intend to use as in fix. E.g.: (1 + 2 ) => (+ 1 2) while (1 |+| 2 ) => (1 |+| 2) Then you could more easily write expressions that would be interpreted the same way on both traditional readers and your new reader. However, if you're not really reading lisp code, then the sky is the limit. Haskell includes its own system, as I'm sure you know. Can you post a few examples of representative expressions, and then maybe we can backtrack to see what alternatives exist? --- David A.Wheeler |
From: Alan M. G. <alm...@gm...> - 2016-09-13 23:23:01
|
On Tue, Sep 13, 2016 at 8:11 AM, David A. Wheeler <dwh...@dw...> wrote: > > >4. Backquotes "invert" the use of a symbol: foo is a prefix symbol, > >`foo` > >is an infix symbol; while + is an infix symbol while `+` is a prefix > >symbol. > > How will you identify quasi quoting? Or do users simply have to use the > full name quasiquote ? > Full name, sadly ^^ The target I'm planning for these rules is not, technically speaking, a Lisp (a dynamically-typed language whose primary data type is used to represent its code) but rather a Haskell-like language. The point of this is to allow a Scheme macro processor to be used on a Haskell-like language. So, quasiquote is a lot less needed. syntax `<-` syntax do . transform . . do . . . p <- x . to $ syntaxError "do: last form cannot be `p <- x'" p . transform . . do . . . x . to . . x . transform . . do . . . p <- x . . . y . . . ... . to . . . x >>= \ p -> do y ... . transform . . do . . . x . . . y . . . ... . to . . x >>= \ _ -> do y ... (well, "\" would also have to be prefix-defaulted, and the "function" syntax would be `->` rather than \ here, with \ being a dummy stand in) Still, let (or "where", which is a more common idiom in Haskell-like languages, although "let" does still exist) is difficult to express in a good indentation form.... fix :: ((a -> b) -> (a -> b)) -> (a -> b) map = value . fix rec . where . . rec map f (a:as) = f a:map f as . . rec map f Nil = Nil {- (map = (value (fix rec) (where ((rec map f (a:as)) = ((f a):(map f as))) ((rec map f NIl) = Nil)))) -} blech! Sincerely, AmkG |
From: David A. W. <dwh...@dw...> - 2016-09-13 00:11:52
|
>4. Backquotes "invert" the use of a symbol: foo is a prefix symbol, >`foo` >is an infix symbol; while + is an infix symbol while `+` is a prefix >symbol. How will you identify quasi quoting? Or do users simply have to use the full name quasiquote ? --- David A.Wheeler |
From: David A. W. <dwh...@dw...> - 2016-09-12 23:50:47
|
Fyi, I've been implementing a library in common lisp using sweet expressions. It is not quite ready for prime time, but you might find it amusing here: https://github.com/david-a-wheeler/cl-metamath --- David A.Wheeler |
From: David A. W. <dwh...@dw...> - 2016-09-12 23:46:55
|
That's a cool approach. That said, I suspect trying to define precedence rules will be a pain in the butt. There is a looming problem if different forms have different presidence rules. You might be better off three defining precedence rules for a subset of operations, and then just requiring people to use parentheses otherwise. --- David A.Wheeler |