Wish list

Started by kks, January 15, 2010, 01:40:43 PM

Previous topic - Next topic

kks

Hi! After learning newLISP for some times, here is my wish list ;-)



1. block/multi-line (nestable) comment; its syntax might be #{...}#



2. .0 is not removed when printing floats (e.g. 1.0 should be printed 1.0, not 1)



3. regex-option parameters should accept nil to mean not using regular expression (e.g. (find "x" "axbxc" nil 2))



4. inc (and dec, sequence, for) should correctly use either integer or floating-point arithmetic based on the type of current value (or of its additional argument) (e.g. (inc 1.2) should be 2.2, not 2; (inc 1 2) should be 3, not 3.0)



5. parameter names can be prefixed (or suffixed) with a marker (says &), and the corresponding arguments would be passed by reference (e.g. (define (my-pop &l (n 0)) (pop &l n)))



6. always return by reference (see http://newlispfanclub.alh.net/forum/viewtopic.php?f=16&t=3433">//http://newlispfanclub.alh.net/forum/viewtopic.php?f=16&t=3433)



I'm not sure whether they will have any impact (backward compatibility, performance, integrity, etc.). What's your opinion?

cormullion

#1
Hi! Yes, I think everyone who uses newLISP wants to modify it... :)



I too have wondered about another multi-line text/comment tag f. Perhaps [comment] [/comment], consistent with [text] and [cmd]. Of course, you can usually use [text] [/text] for comments anyway...



Can't see the need for nil in find...



Personally I'm OK with the existing float/integer conversions in newLISP, although I can see that they might cause problems if you haven't found out about them - and some people find out the hard way that + and - do integer arithmetic... Perhaps inc and dec could be smarter without hardship though...  



As for backwards compatibility - I have my own opinions! :) I'm ok with incompatible changes if there are substantial benefits in return, but it's less satisfactory when they're just minor compatibility issues or things that could easily be customized locally with a function or two. And maintaining two parallel bits of code for two or more releases is a bit of a chore. I prefer new powerful functions or extended functionality from existing functions!



I think that some of the goals of newLISP are to be as simple as possible, as small as possible, as powerful as possible, and as fast as possible. If you can argue that a change you're proposing can help move towards all of those goals, Lutz may not be able to resist implementing it!

kks

#2
Thank cormullion for your feedback.



As for block comment, a string cannot be used as an alternative for a comment in all places. For example, to "comment-out" an item (2) in a list, compare:

(list 1 "2" 3)  # use string, not valid

(list 1
 # 2   # use single-line comment, ok but need to reformat code
  3 )

(list 1 #{2}# 3)   # if block comment is supported

And for the syntax, frankly, I don't like [text]...[/text], [cmd]...[/cmd], [comment]...[/comment]. I think its too verbose.



As for nil in 'find' function, if I want to find a (non-regex) substring p in a string s starting at an index position i:

(find p (slice s i))   # work, but isn't slice will allocate memory; what if s is a very large string

(find (regex-quote p) s 0 i)   # work, if we have defined 'regex-quote' ourselves, it's not built-in

(find p s nil i)   # error, nil is not a number!


And for inc/dec:

(inc 1.2)   # => 2, is this expected in most cases?

(float? (inc 1 1))  # => true!


I know that some changes can be implemented by defining my own functions (e.g. my-print, my-inc), but I think they are "normal" and should be "built-in".

cormullion

#3
Hi again! We can chat all day about this... :)



I know what you mean about verbosity in the language. However, I think that one of the characteristic of Lutz' newLISP approach is a preference for avoiding puntuation-heavy syntax, so the more verbose versions of things like [text] seem to win out over more compact and possibly ugly character combos. I like that, but I can see your point - an inline comment could be useful.


Quoteif I want to find a (non-regex) substring p in a string s starting at an index position i

I'm still struggling with this one. I would have this thought this would work:


(find p (i s))
(find p (i s) 0) ; regex


As for inc - well, you could argue that its main purpose is for incrementing symbols or list elements, and if you're relying on it to do your arithmetic you might be better off  using + or add... That's not to say that it's not got it's surprises, though. Luckily the Introduction to newLISP has covered this area... :)



While we're talking about wish lists, how about a built-in version of this:


(define-macro (extend)
  (setf (eval (args 0)) (append (eval (args 0)) (eval (args 1)))))


which is defined to fill the gap between set ...append and push:


(set 'lst  (sequence 0 10))
(push (sequence 11 20) lst -1)
;-> (0 1 2 3 4 5 6 7 8 9 10 (11 12 13 14 15 16 17 18 19 20))

(set 'lst (sequence 0 10))
(set 'lst (list lst (sequence 11 20)))
;-> ((0 1 2 3 4 5 6 7 8 9 10) (11 12 13 14 15 16 17 18 19 20))

(set 'lst (sequence 0 10))
(set 'lst (append lst (sequence 11 20)))
;-> (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)

(set 'lst (sequence 0 10))
(extend lst (sequence 11 20))
;-> (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)


And a duplicates function to go with intersect and difference... But I can define my own versions, for now...

Lutz

#4
Quoteif I want to find a (non-regex) substring p in a string s starting at an index position


take a slice of s:


> (set 's "abcdefg")
"abcdefg"
> (find "de" (2 s))
1


http://www.newlisp.org/downloads/newlisp_manual.html#slice">http://www.newlisp.org/downloads/newlis ... html#slice">http://www.newlisp.org/downloads/newlisp_manual.html#slice

TedWalther

#5
For the inc/dec request, I must concur.  The int/float conversion rules are confusing.



Could we have ++ and -- for integer operations, and inc/dec for floating operations?  This would be consistent with the difference between + and add.



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

TedWalther

#6
For the multiline comment, couldn't you just make  "comment" macro?  For instance,



(comment

blah blah blah

...

)
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

xytroxon

#7
I would support the addition of the following two Scheme comment forms:



#;(s-expression)



#| block comment |#



Since the newLISP parser already checks for # comments, this would have the least impact when implementing. (And the Schemers have already fought out the "correct and proper" syntax for us, so text editors hopefully will suport it too  ;p)



http://en.wikipedia.org/wiki/Scheme_%28programming_language%29#Comments">//http://en.wikipedia.org/wiki/Scheme_(programming_language)#Comments
QuoteComments



Up to the R5RS standard, the standard comment in Scheme was a semicolon, which makes the rest of the line invisible to Scheme. Numerous implementations have supported alternative conventions permitting comments to extend for more than a single line, and the R6RS standard permits two of them: an entire s-expression may be turned into a comment (or "commented out") by preceding it with #; (introduced in SRFI 62 [17]) and a multiline comment or "block comment" may be produced by surrounding text by #| and |#.


-- xytroxon
\"Many computers can print only capital letters, so we shall not use lowercase letters.\"

-- Let\'s Talk Lisp (c) 1976

kks

#8
Lutz,

Yes `slice` works, but in this case it will unnecessary allocate memory, right? It's not good if (find p (i s)) is used in a loop, when s is very large.



TedWalther,

comment macro does not work.

(define-macro (comment))
(list 1 (comment 2) 3)   # => (1 nil 3), not (1 3)


xytroxon,

In my opinion, I think #{...}# is better than #|...|#, because it's easier to match the end of comment by using `%` in vim.

Lutz

#9
Thanks for all the suggestions. Some of them are covered in the next release.

Kazimir Majorinc

#10
Maybe some more general solution



(modify 'x + y) <=> (set 'x (+ x y))

(modify 'x append y) <=> (set 'x (append x y))



(modifyf x append y z) <=> (setf x (append x y z))

(modifyf x + y) <=> (setf x (+ x y))



This allows for slightly shorter, flatter but also slightly faster code, and weight is only one or two extra symbols.



For inc, I agree with Ted, ++ is constent here.



 (I'd repeat my old proposal for +., *. etc for floating point +, * etc.)
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.

cormullion

#11
Look forward with interest, Lutz - and slight trepidation... :)



Just thinking out loud - is there any use for a function that doesn't return anything at all? This could have various uses - Ted's comment idea - and other people have asked about the silent function. Yes, it would be inconsistent and a bit odd, but possibly useful in a number of different contexts...

kks

#12
Thanks a lot, Lutz! Curious about which wishes will come true ;-)



Kazimir, I like your floating-point operators (+., *., etc), first found it in your library, and hope they will be built-in too, so they will be standard names. Currently I do:

(setq +. add  -. sub  *. mul  /. div  %. mod)


As for, `modify`, I think using `$it` with `set` is OK

(setq x (+ $it y))
(setq x (append $it y z))

m i c h a e l

#13
Well, here comes my two cents ;-)



Block comments would be nice, but I've been getting along without them. I can see where they would save a lot of work without editor support, though.



I like the symmetry of ++/inc and +/and, but I also like Kazimir's Caml-like +., -., etc., for the floating point versions of these operators, which contradicts the first option. ++. and --. perhaps? :-)



cormullion's suggestion sounds like a void function:


> (println "a" "b" "c")
abc
"c"
> ;; simulating a void function:
> (define (void) (silent) (print "> "))
(lambda () (silent) (print "> "))
> (void)
> (begin (println "a" "b" "c") (void))
abc
> _


I do find it distracting sometimes to see the output and the result from the print functions together. Since silent even silences the prompt, I often type (print "> ") at the end of my calls to silent so I'm not confused by the missing prompt.



Thanks for reminding me about the use of $it within the set functions, kks. I had forgotten about that.



Let's see, that looks to add up to about 1-3/4 cents. Close enough!



m i c h a e l

cormullion

#14
hi m i c h a e l! Nice to see you again. A nice void you've gotten us into, although yours is a cheshire-cat of a function, leaving a grin behind:


(list "a" "b" (void) "d")
-> ("a" "b" nil "d")


- it's whimsical, but I'm not sure it makes for readable inline comments anyway...