newLISP Fan Club

Forum => newLISP newS => Topic started by: cormullion on September 18, 2008, 03:02:02 PM

Title: set-nth on strings
Post by: cormullion on September 18, 2008, 03:02:02 PM
How would I do this in newLISP 9.9...


newLISP v.9.3.0 on OSX UTF-8, execute 'newlisp -h' for more info.

> (set 's "abc")
"abc"
> (set-nth 0 s "z")
"zbc"


Is this a job for setf now...?
Title:
Post by: Lutz on September 18, 2008, 06:28:06 PM
Most of the following would work in either 9.3, 9.4 or 9.9.x -> 10.0 versions. If not it is noted.



The easiest would be:


(set 's "abc")

(replace "a" s "z") => "zbc"


which assumes you know that the first character is a "a"; if not, you could work on the string with regular expressions:


(set 's "abc")

(replace "^." s "z" 0) => "zbc"


'replace' has also the advantage, that is returns a string reference in 9.9x and after, so you could do:


; v 9.9.2 and after only
(set 's "abc")

(pop (replace "a" s "z") -1) => "c"

s => "zb"


Replace together with regular expressions is probably the most versatile in string manipulation, but there are also combinations of 'string', 'rest' and 'sclice' which are useful.


(set 's "abc")

(set 's (string "z" (rest s))) => "zbc"

(set 's (string "z" (1 s))) => "zbc"


Then there is also 'push' and 'pop' which can insert or extract single or multi-character pieces from a string:


(set 's "abc")

(pop s) (push "z" s)

s => "zbc"


All of these of course would work with multi-character strings to extract or insert (including 'push' and 'pop')
Title:
Post by: newBert on September 19, 2008, 12:27:18 AM
This can work too:


> (set 's "abc")
"abc"
> (replace (first s) s "z") ; or (replace (s 0) s "z")
"zbc"

:)
Title:
Post by: cormullion on September 19, 2008, 09:16:22 AM
But you're saying that you're removing the ability to directly modify strings using indexes to character locations?



(replace (nth i s) s "") is OK but not as good as (nth-set - the repetition of the string...



And I used to like the way that many functions such as nth-set worked on both strings and lists... Made newLISP easy to learn, I thought.



I'm trying hard to like newLISP 10 but I'm not finding it very likeable yet...
Title:
Post by: Lutz on September 19, 2008, 10:53:02 AM
I have 'setf' working on string references: (setf (s idx) str) . But cannot guarantee yet that this will stay (it is not thought thru fully and not enough tested yet).



From the beginning I have been aware of the loss of old 'set-nth' for strings (and some other things), but still think that the improvements overall outweigh the loss of other conveniences.



But perhaps we are lucky and can have it all ;-)
Title:
Post by: DrDave on September 19, 2008, 12:35:58 PM
Quote from: "cormullion"But you're saying that you're removing the ability to directly modify strings using indexes to character locations?



(replace (nth i s) s "") is OK but not as good as (nth-set - the repetition of the string...



And I used to like the way that many functions such as nth-set worked on both strings and lists... Made newLISP easy to learn, I thought.



I'm trying hard to like newLISP 10 but I'm not finding it very likeable yet...

But if it goes away and you really find it useful, it's not hard in newLISP to write your own implementation of nth-set.
Title:
Post by: cormullion on October 25, 2008, 02:57:34 PM
Quote from: "Lutz"I have 'setf' working on string references: (setf (s idx) str) . But cannot guarantee yet that this will stay


do you think it'll make the v10 release?
Title:
Post by: Kazimir Majorinc on October 26, 2008, 01:31:20 AM
Reviewing the situation, I now incline to Cormullion's side and I think set-nth and nth and company should be kept. The main reason is that "implicit indexing" of the syntax is on the way of elimination of lambda in Pico Lisp style. It could be one of the big issues in future Lisps, especially in Newlisp. On the other side, implicit indexing is irregular syntax that has some - but little advantage, while it has more disadvantages.



I think it would be best
  • * to undefine (L idx) as evaluable expression. ('(4 5) 1) should return error,

    * to keep (L i) syntax to some extent in function calls, like (nth (L i)) and (set-nth (L i) x). Still, the functions with different names, like (set-nthx L i x) and (set-nthi (L i) x) have sense,

    * to define polymorphic versions like setf on the base of specific versions setq, set-nth, but not to dump specific versions.

So, it is not completely lost case for polymorphism, but I think that specific versions have important advantages:
  • * its easier to analyze program if it contains specific information,

    * specific functions are slightly faster,

    * polymorphism depends on context. For example, there are many ways to define product on list.
Title:
Post by: Lutz on October 26, 2008, 03:34:44 AM
Regarding 'setf' for strings:


Quotedo you think it'll make the v10 release?


it is already there since 9.9.4 and you can find examples in the reference section of the manual http://www.newlisp.org/downloads/development/newlisp_manual.html#setf


QuoteI think set-nth and nth and company should be kept


'nth' is still there, implicit indexing is purely optional and both explixit and implicit indexing works with 'setf'


(set 'lst '(a b c))

(setf (nth 1 lst) 'B) ; explicit for better readability

lst => (a B c)

(setf (lst 1) 'Z) ; implicit and higher speed

lst => (a Z c)


'setf' when used with explicit 'nth' or 'first' or 'last' is still descriptive when reading source.



Implicit indexing means overloading the string, list or array data type with operator functionality and fits well into the LISP evaluation paradigm (see here: http://www.newlisp.org/ExpressionEvaluation.html ). The same is done with numbers for implicit slicing or the context symbol in operator position, where it gets interpreted as the default functor <symbol>:<symbol>.



Implicit indexing has been received enthusiastically by many since version 8.5 more than three years ago, and newLISP was the first to introduce it (Arc adopted it too). It brings Lisp closer to other programming languages where the combination of container and index to express a place in that container, is a common thing to do. 'setf' ties it together with other parts of the language. Where implicit indexing obscures code readability explicit indexing and slicing can still be used.



Ps: note that list or string slices are not a valid place (yet) to use 'setf', use a combination of 'pop' and 'push' instead.
Title:
Post by: cormullion on October 26, 2008, 03:53:27 AM
Oh yes, so it is! I'm sorry.



I'm switching between newLISP versions quite often at the moment, and I re-installed 9.9.2 by mistake...



You're up early today Lutz!