(but-last) ?

Pondering the philosophy behind the language
Locked
Excalibor
Posts: 47
Joined: Wed May 26, 2004 9:48 am
Location: Madrid, Spain

(but-last) ?

Post by Excalibor »

Hi there,

This is a problem that has arisen several times now in my programs (which do some heavy text file parsing)

I get a text line, (parse) it and then I need a list of tokens but the last one.

A silly example: getting the base URI from a given URI:

"http://example.com/path/to/files/file1.html"

There's surely a hundred ways to do this, but I simply (parse) it given all possible token separators and I get the list

("http" "example.com" "path" "to" "files" "file1.html")

I needed a simple (but-last) function to get all elements but the last one to use is some loops:

I came with different solutions, these are my favourites:

Code: Select all

(define (but-last lst)
  (rest (rotate lst)))

(define (but-last2 lst)
  (1 (- (length lst) 1) lst))

(define (but-last3 lst)
  (chop lst))
You see, the first one is "less optimal" than the second, but it only mentions lst once and, alas, is more useful to on-the-fly generated lists . OTOH performance is not that horrible, so it's a nice hack (instead of slicing, twisting, kind of) :-)

Then, reading more into the documentation, I arrived to chop. Doh!

So...

We have an asymmetry in here:

Code: Select all

'(this is a list)

 first    rest

 chop     last
So, maybe an alias chop = but-last, except-last, almost-all, firsts could be useful?

I mean, we have the "first" and the "rest" of a list, we could have the "firsts" and the "last"? The truth is (chop) is not an intuitive name for this task, even when it's covered by it.

In my view, the fact that newLISP treats strings and lists the same for many different kind of things is not a favor in this case. I'm thinking in the new user, because I'm a kind-of new user, and, well, you know... :-P

Anyway, your thoughts?

laters

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: (but-last) ?

Post by xytroxon »

Time for newLISP's implicit indexing to come to the rescue!!! ;)
Implicit indexing for rest and slice

Implicit forms of rest and slice can be created by prepending a list
with one or two numbers for offset and length. If the length is
negative it counts from the end of the list or string:
If implict indexing looks messy to your coding style, create a function:

Code: Select all

(define (drop-last var)(0 -1 var))
Then...

Code: Select all

(drop-last '("http" "example.com" "path" "to" "files" "file1.html"))
-> ("http" "example.com" "path" "to" "files")
-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

I'm not sure I'd consider such an easy to do task worthy of a new function all of its own ... most is quite fun, but a bit vague for some, perhaps.

but-first and but-last would be symmetrical alternatives.
The truth is (chop) is not an intuitive name for this task, even when it's covered by it.
Well it's quite a good name for the task. in many ways, just not symmetrical like first/rest/last.

Excalibor
Posts: 47
Joined: Wed May 26, 2004 9:48 am
Location: Madrid, Spain

Post by Excalibor »

cormullion wrote:I'm not sure I'd consider such an easy to do task worthy of a new function all of its own ... most is quite fun, but a bit vague for some, perhaps.

but-first and but-last would be symmetrical alternatives.
The truth is (chop) is not an intuitive name for this task, even when it's covered by it.
Well it's quite a good name for the task. in many ways, just not symmetrical like first/rest/last.
Yes, please don't misunderstand me, chop is great name, and applied to strings is actually a kind of standard (at least from a Perl/PHP POV), and extending it to lists is actually just as natural...

I was just thinking that if I can make that error, someone else could do it (please don't tell me I'm the only moron around! ;-) and following the Principle of Least Surprise, I'd prefer "nicer" names, even if I will surely use implicit splitting (i don't really use first, etc on quick scripts, but I tend to use them in more permanent things, as they express the code intention in a clearer, if you'll allow me, way.

but-first and but-last would really be great as names, they are clear and predictable, once you see the others around.

Another possibility, in a different plane, would be to allow for an extra index to first, such as (first lst n) would take the first n elements... (first lst -1) would "naturally" take all the first ones but the last one... :-P

Thanks for your comments, anyway, as I can easily gather these aliases in a common library for use and abuse :-P

Excalibor
Posts: 47
Joined: Wed May 26, 2004 9:48 am
Location: Madrid, Spain

Re: (but-last) ?

Post by Excalibor »

xytroxon wrote:Time for newLISP's implicit indexing to come to the rescue!!! ;)

...

Code: Select all

(drop-last '("http" "example.com" "path" "to" "files" "file1.html"))
-> ("http" "example.com" "path" "to" "files")
Yeah, it's actually something that doesn't easily arise just by browsing the functions index when reading the documentation... That's why I was proposing an alias, so it's easier to find just by looking... Implicit is cool, but for newbies, explicit is better :-)

thanks anyway!

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

for all implicit forms there is also a named function, look into 'slice':
http://www.newlisp.org/newlisp_manual.html#slice

Locked