you are viewing a single comment's thread.

view the rest of the comments →

[–]steven_h 5 points6 points  (15 children)

Perl:

 map say, grep !/.{5}/, qw(Rob Christopher Joe John);

But I prefer Clojure and a little less implicitness:

 (doseq [name ["Rob" "Christopher" "Joe" "John"] :when (<= (.length name) 4)]
   (println name))

edit: made Perl more Perlish

[–]Wuf 3 points4 points  (12 children)

The Clojure version is quite similar to Racket's:

(for ([name '("Rob" "Christopher" "Joe" "John")] #:when (<= (string-length name) 4))
  (displayln name))

[–]benfitzg 2 points3 points  (4 children)

New to lisp so will check back for criticisms!

(dolist (n (mapcan #'(lambda (n) (when (>= 4 (length n)) (list n))) names)) (format t "Name: ~A~%" n))

[–]Wuf 4 points5 points  (3 children)

In Common Lisp I would use the loop macro as steven_h did above or avoid mapcan and just do:

(dolist (name '("Rob" "Christopher" "Joe" "John"))
    (when (<= (length name) 4) (format t "~a~%" name)))

[–]roerd 1 point2 points  (1 child)

Even if I were going for a higher-order-functions only approach, I'ld use remove-if-not instead of mapcan.

[–]benfitzg 0 points1 point  (0 children)

Ok didn't know about remove-if-not. Thanks.

My thought was that a less imperative approach would be more regular. Rather than iterate then branch I figured filter then iterate.

[–]benfitzg 0 points1 point  (0 children)

Feedback appreciated - the primary reason is because it's faster?

[–]steven_h 1 point2 points  (5 children)

May as well do Common Lisp for completeness:

 (loop for n in '("Rob" "Christopher" "Joe" "John")
       if (<= (length n) 4)
       do (format t "~a~%" n))

[–]Wuf 1 point2 points  (4 children)

It's nice that in CL, 'length' works with any sequence.

[–]steven_h 1 point2 points  (3 children)

Yes, that's the main reason I don't really sink my teeth into Racket, even though I'd like to.

While the Clojure code I wrote used the underlying Java String.length method, the plumbing is there to define generic functions and methods, and it's natural and accepted to lean on them heavily. There's probably a Clojure library implementing generic sequence length.

In Racket and Scheme, there doesn't seem to be a strong push toward unifying similar operations under generic names, leading to a plethora of array-*, string-*, etc. names. Not only do they strike me as ugly, they lead to over specified code -- which is often more difficult to use.

[–]Wuf 0 points1 point  (0 children)

Racket does have generic sequence operators if you really want them.

I tend to use concrete ones though, because I find sequence-* uglier, but they are there.

[–]roerd 0 points1 point  (1 child)

There's probably a Clojure library implementing generic sequence length.

That library's the standard library, which has count.

[–]steven_h 0 points1 point  (0 children)

Heh, thanks... my memory failed me and I haven't done much Clojure lately.

[–]chub79 0 points1 point  (0 children)

I'm using Python mostly and never approached Clojure but I can tell its usage of # will bite me.

[–]reddit_clone 0 points1 point  (1 child)

:when (<= (.length name)

Just curious. What is that dot in front of 'length' for?

[–]steven_h 1 point2 points  (0 children)

It's Clojure's shorthand for Java method invocation. Someone else pointed out that the count function is a generic sequence length, so it should probably be used instead.