Page 1 of 1

set-nth on strings

Posted: Thu Sep 18, 2008 10:02 pm
by cormullion
How would I do this in newLISP 9.9...

Code: Select all

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...?

Posted: Fri Sep 19, 2008 1:28 am
by Lutz
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:

Code: Select all

(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:

Code: Select all

(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:

Code: Select all

; 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.

Code: Select all

(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:

Code: Select all

(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')

Posted: Fri Sep 19, 2008 7:27 am
by newBert
This can work too:

Code: Select all

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

Posted: Fri Sep 19, 2008 4:16 pm
by 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...

Posted: Fri Sep 19, 2008 5:53 pm
by Lutz
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 ;-)

Posted: Fri Sep 19, 2008 7:35 pm
by DrDave
cormullion wrote: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.

Posted: Sat Oct 25, 2008 9:57 pm
by cormullion
Lutz wrote: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?

Posted: Sun Oct 26, 2008 8:31 am
by Kazimir Majorinc
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.

Posted: Sun Oct 26, 2008 10:34 am
by Lutz
Regarding 'setf' for strings:
do 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/develo ... .html#setf
I 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'

Code: Select all

(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.

Posted: Sun Oct 26, 2008 10:53 am
by cormullion
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!