Discussion:
string to list or string to array
(too old to reply)
Swami Tota Ram Shankar
2012-10-21 10:37:08 UTC
Permalink
Friends, I am trying to read text from a file opened in emacs and
recognize it as array or list so that I can do some vector additions
using mapcar.

I am mainly stuck at the stage of converting the string text to array
or list.

The method which I use to locate the text is "looking-at" function and
the regexp works.

(when (looking-at "[[0-9.+-\\ ]+]")

some code that is to play around for debugging and messaging and
checking the match
(forward-char (+ (string-width (match-string 0)) 1))
(setq V (match-string 0))
(setq V (intern (match-string 0)))


The cursor is placed on the start bracket, ie "["

and text looks like for example array of indefinite length

[17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]


Please suggest some different solutions that can take the string
matched, match-string for example and convert to a list or an array on
which I can do mapcars or lambdas.

Thanks
Swami
Pascal J. Bourguignon
2012-10-21 11:16:37 UTC
Permalink
Post by Swami Tota Ram Shankar
Friends, I am trying to read text from a file opened in emacs and
recognize it as array or list so that I can do some vector additions
using mapcar.
I am mainly stuck at the stage of converting the string text to array
or list.
The method which I use to locate the text is "looking-at" function and
the regexp works.
(when (looking-at "[[0-9.+-\\ ]+]")
^^
12

The character 1 has the meaning you'd want the character 2 to have.

Your regexp parses as:

one or more of any character in "[0123456789.+- "
followed by "]".

You want:

(looking-at "\\[[0-9.+-\\ ]+\\]")

The third backslash is optional, but I add it for clarity.
Post by Swami Tota Ram Shankar
some code that is to play around for debugging and messaging and
checking the match
(forward-char (+ (string-width (match-string 0)) 1))
(setq V (match-string 0))
(setq V (intern (match-string 0)))
The cursor is placed on the start bracket, ie "["
and text looks like for example array of indefinite length
[17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]
Please suggest some different solutions that can take the string
matched, match-string for example and convert to a list or an array on
which I can do mapcars or lambdas.
Since the syntax of this text is exactly the printed representation of
an emacs lisp vector, you can read it directly with read.

(defun get-vectors-from-buffer ()
(let ((vectors '()))
(goto-char (point-min))
(while (re-search-forward "\\[[0-9.+-\\ ]+\\]" nil t)
(goto-char (match-beginning 0))
(push (read (current-buffer)) vectors))
(nreverse vectors)))

;; [1 2 3.0] [4 5 6]
;; [7 +8 -9]

(get-vectors-from-buffer)
--> ([[0-9\.+-\\] +]
[[0-9\.+-\\] +\\]
[17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]
[[0-9\.+-\\] +\\]
[1 2 3.0]
[4 5 6]
[7 8 -9])
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Swami Tota Ram Shankar
2012-10-21 19:03:10 UTC
Permalink
Post by Swami Tota Ram Shankar
Friends, I am trying to read text from a file opened in emacs and
recognize it as array or list so that I can do some vector additions
using mapcar.
I am mainly stuck at the stage of converting the string text to array
or list.
The method which I use to locate the text is "looking-at" function and
the regexp works.
(when (looking-at "[[0-9.+-\\ ]+]")
                     ^^
                     12
The character 1 has the meaning you'd want the character 2 to have.
     one or more of any character in "[0123456789.+- "
     followed by "]".
      (looking-at "\\[[0-9.+-\\ ]+\\]")
The third backslash is optional, but I add it for clarity.
Post by Swami Tota Ram Shankar
some code that is to play around for debugging and messaging and
checking the match
(forward-char (+ (string-width (match-string 0)) 1))
(setq V (match-string 0))
(setq V (intern (match-string 0)))
The cursor is placed on the start bracket, ie "["
and text looks like for example array of indefinite length
[17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]
Please suggest some different solutions that can take the string
matched, match-string for example and convert to a list or an array on
which I can do mapcars or lambdas.
Since the syntax of this text is exactly the printed representation of
an emacs lisp vector, you can read it directly with read.
(defun get-vectors-from-buffer ()
   (let ((vectors '()))
     (goto-char (point-min))
     (while (re-search-forward "\\[[0-9.+-\\ ]+\\]" nil t)
        (goto-char (match-beginning 0))
        (push (read (current-buffer)) vectors))
     (nreverse vectors)))
;; [1 2 3.0] [4 5 6]
;; [7 +8 -9]
(get-vectors-from-buffer)
--> ([[0-9\.+-\\] +]
     [[0-9\.+-\\] +\\]
     [17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]
     [[0-9\.+-\\] +\\]
     [1 2 3.0]
     [4 5 6]
     [7 8 -9])
Hi Pascal, Thanks for the reply but there are some problems. I
understood your change to regexp.

However, you are doing too much in your and I need only read one
string at a specific location at a time, not the whole buffer.

Thus, I am having difficulty and need help. Let me write the modified
story again.

(when (looking-at "\\[[0-9.+-\\ ]+\\]")
(forward-char (+ (string-width (match-string 0)) 1))
(setq V (match-string 0))
(setq V (read-from-string (intern (match-string 0))))
;(setq V (read-from-string "[17.16 -17.16 17.16 17.16 17.16 17.16
17.16 17.16]" ))


; (insert (match-string 0)) ; print the entire matched
string
;(insert (format "%s" V))
(insert (format "%s" (car (split-string (format "%s" V) " "))))
;; (setq X (make-vector
;; (/ (length V ) 2)
;; 3 )


)
[17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]


I am using

read-from-string

and I need to get it to work.

but it gives error

Debugger entered--Lisp error: (wrong-type-argument stringp \[17\.16\
-17\.16\ 17\.16\ 17\.16\ 17\.16\ 17\.16\ 17\.16\ 17\.16\])
read-from-string(\[17\.16\ -17\.16\ 17\.16\ 17\.16\ 17\.16\ 17\.16\
17\.16\ 17\.16\])
eval((read-from-string (intern (match-string 0))))
eval-last-sexp-1(nil)
eval-last-sexp(nil)
* call-interactively(eval-last-sexp)


If I dont use intern, I get some small little thing.

(read-from-string "[17.16 -17.16 17.16 17.16 17.16 17.16 17.16
-17.16]" ))

([17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16] . 51)

so I can car it.

should I be using match-string or data-match or match-data to most
simply get it working while using "looking-at" ?

so the parsing works which a hard wired string as in the sequential
execution below, but the problem is that its not working with match-
string.

(setq V (car (read-from-string "[17.16 -17.16 17.16 17.16 17.16 17.16
17.16 -17.16]" )))
(mapcar* (lambda(x y)(+ x y)) V V)


Thanks.
Pascal J. Bourguignon
2012-10-21 20:22:40 UTC
Permalink
Post by Swami Tota Ram Shankar
Post by Pascal J. Bourguignon
Since the syntax of this text is exactly the printed representation of
an emacs lisp vector, you can read it directly with read.
(defun get-vectors-from-buffer ()
   (let ((vectors '()))
     (goto-char (point-min))
     (while (re-search-forward "\\[[0-9.+-\\ ]+\\]" nil t)
        (goto-char (match-beginning 0))
        (push (read (current-buffer)) vectors))
     (nreverse vectors)))
;; [1 2 3.0] [4 5 6]
;; [7 +8 -9]
(get-vectors-from-buffer)
--> ([[0-9\.+-\\] +]
     [[0-9\.+-\\] +\\]
     [17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]
     [[0-9\.+-\\] +\\]
     [1 2 3.0]
     [4 5 6]
     [7 8 -9])
Hi Pascal, Thanks for the reply but there are some problems. I
understood your change to regexp.
However, you are doing too much in your and I need only read one
string at a specific location at a time, not the whole buffer.
Thus, I am having difficulty and need help. Let me write the modified
story again.
(when (looking-at "\\[[0-9.+-\\ ]+\\]")
(forward-char (+ (string-width (match-string 0)) 1))
(setq V (match-string 0))
(setq V (read-from-string (intern (match-string 0))))
0- What's the purpose of moving the point?
1- Don't use setq, use let.
2- Don't bind two different things to the same variable!
3- read-from-string reads from a string, not a symbol, so why are you
interning a symbol?

Let me advise you to read:

An Introduction to Programming in Emacs Lisp
http://www.gnu.org/software/emacs/emacs-lisp-intro/ or M-: (info "(eintr)Top") RET




(defun get-vector-at-point ()
(when (looking-at "\\[[0-9.+-\\ ]+\\]")
(goto-char (match-beginning 0))
(read (current-buffer))))
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Swami Tota Ram Shankar
2012-10-23 01:16:58 UTC
Permalink
Post by Pascal J. Bourguignon
Post by Swami Tota Ram Shankar
Post by Pascal J. Bourguignon
Since the syntax of this text is exactly the printed representation of
an emacs lisp vector, you can read it directly with read.
(defun get-vectors-from-buffer ()
   (let ((vectors '()))
     (goto-char (point-min))
     (while (re-search-forward "\\[[0-9.+-\\ ]+\\]" nil t)
        (goto-char (match-beginning 0))
        (push (read (current-buffer)) vectors))
     (nreverse vectors)))
;; [1 2 3.0] [4 5 6]
;; [7 +8 -9]
(get-vectors-from-buffer)
--> ([[0-9\.+-\\] +]
     [[0-9\.+-\\] +\\]
     [17.16 -17.16 17.16 17.16 17.16 17.16 17.16 17.16]
     [[0-9\.+-\\] +\\]
     [1 2 3.0]
     [4 5 6]
     [7 8 -9])
Hi Pascal, Thanks for the reply but there are some problems. I
understood your change to regexp.
However, you are doing too much in your and I need only read one
string at a specific location at a time, not the whole buffer.
Thus, I am having difficulty and need help. Let me write the modified
story again.
(when (looking-at "\\[[0-9.+-\\ ]+\\]")
(forward-char (+ (string-width (match-string 0)) 1))
(setq V (match-string 0))
(setq V (read-from-string (intern (match-string 0))))
0- What's the purpose of moving the point?
1- Don't use setq, use let.
2- Don't bind two different things to the same variable!
3- read-from-string reads from a string, not a symbol, so why are you
   interning a symbol?
          An Introduction to Programming in Emacs Lisp
         http://www.gnu.org/software/emacs/emacs-lisp-intro/ or  M-: (info "(eintr)Top") RET
   (defun get-vector-at-point ()
     (when (looking-at "\\[[0-9.+-\\ ]+\\]")
       (goto-char (match-beginning 0))
       (read (current-buffer))))
Hi Pascal,

I like your advice above a lot, especially concerning setq versus let.

I will later ask you to elaborate more on your point (2), however, for
now I want to focus solely on point (1).


I had to write a wrapper function to one I was writing and I soon ran
into a name space conflict because of setq. Temporarily I relieved,
due to the urgency to complete the task, by renaming the variables.

However, I want an expert such as you to address some style issues in
lisp programming. For this reason, I am renaming my post as

Style Issues in Lisp and Scheme programming, setq versus let

Here are my questions.

Does setq cause some kind of permanent persistence of the variable
like a global?

In the lingo of computer science, such as lexical scoping, dynamic
scoping, static binding, dynamic binding, what is its meaning and what
is the meaning of these four terms?

Even more important question is the impact on program structure and
readability.

For example, the imperative programming style, flows nicely from top
to bottom. The eye has to move L->R and top to bottom to understand
the screenful module, as in C.

I have found that let, and functional style leads to an onion type
structure.

f(g(h(x,y),z,k(alpha,beta,l(theta)))w)

If it is short, its not an issue, but the multiple cores or eyes of
the onion, makes it impossible to grasp the structure.

I ask you to focus your brain intensely and come up with some
COMPELLING rules of thumb, so I can write programs that are readable.

I know, some of you are such brilliant minds that there will not
emerge one in maybe 100 years as smart as you, so write these rules
for newbies.

and sprinkle some examples.

I want to apply to my own thing, but you also tell us how to read
these programs since when I look at yours, it becomes digestable only
after persisting with it and going to the cores and reading inward
out.

Whats your method or habit of reading?

Swami
Swami Tota Ram Shankar
2012-10-23 03:02:00 UTC
Permalink
On Mon, Oct 22, 2012 at 6:16 PM, Swami Tota Ram Shankar
Post by Swami Tota Ram Shankar
For example, the imperative programming style, flows nicely from top
to bottom. The eye has to move L->R and top to bottom to understand
the screenful module, as in C.
I have found that let, and functional style leads to an onion type
structure.
f(g(h(x,y),z,k(alpha,beta,l(theta)))w)
That could be valid C code, but it's probably not Lisp code, unless
you really do have a function named "x,y".
Post by Swami Tota Ram Shankar
If it is short, its not an issue, but the multiple cores or eyes of
the onion, makes it impossible to grasp the structure.
Just one small tip: when reading lisp code, pay more attention to the
indentation then to the parentheses.  Of course the
compiler/interpreter doesn't pay attention to the indentation, but the
author probably did.
Can you suggest some skeleton

(defun function (var1 var2 var3)
""
(interactive "swith strings and \ns to allow suggested defaults and
avoid typing and simply RTN")

taking care of defaults if null or ""

(let* (()()())



)

)


btw, lisp's prefix notation, (f x y z) is more expressive and
convenient for expressing currying (((f x) y) z) than f(x y z).

I expect incisive and penetrating analysis of code organization and
using that to improve readability.
Stefan Monnier
2012-10-24 15:03:28 UTC
Permalink
btw, Lisp's prefix notation, (f x y z) is more expressive and
convenient for expressing currying (((f x) y) z) than f(x y z).
With all due respect to Lisp, that's not true. Curried calls in the
non-Lisp syntax are simply "f(x)(y)(z)" or even better "f x y z".


Stefan
g***@hotmail.com
2012-10-25 03:20:32 UTC
Permalink
btw, Lisp's prefix notation, (f x y z) is more expressive and
convenient for expressing currying (((f x) y) z) than f(x y z).
With all due respect to Lisp, that's not true.  Curried calls in the
non-Lisp syntax are simply "f(x)(y)(z)" or even better "f x y z".
        Stefan
As an aside you show the notation. well and good. But I realize that
there is no executable substitute or ability to return a curried
function
in emacs. Consider these forms.

(+ 2 3 4) ;; executable
(((+ 2) 3) 4) ;; not executable
(cons '+ (cons 2 (cons 3 (cons 4 nil)))) ;; ditto
(eval '(+ (cons 2 (cons 3 (cons 4 nil))))) ;; ditto

Can anyone suggest an executable version of first in terms of curried
addition?

Since Pascal is busy, and David Kastrup is not seen for quite some
time, I hope someone can give a reply to the question of the thread.

G
Pascal J. Bourguignon
2012-11-21 21:56:55 UTC
Permalink
Post by g***@hotmail.com
btw, Lisp's prefix notation, (f x y z) is more expressive and
convenient for expressing currying (((f x) y) z) than f(x y z).
With all due respect to Lisp, that's not true.  Curried calls in the
non-Lisp syntax are simply "f(x)(y)(z)" or even better "f x y z".
        Stefan
As an aside you show the notation. well and good. But I realize that
there is no executable substitute or ability to return a curried
function
in emacs. Consider these forms.
(+ 2 3 4) ;; executable
(((+ 2) 3) 4) ;; not executable
(cons '+ (cons 2 (cons 3 (cons 4 nil)))) ;; ditto
(eval '(+ (cons 2 (cons 3 (cons 4 nil))))) ;; ditto
Can anyone suggest an executable version of first in terms of curried
addition?
Since Pascal is busy, and David Kastrup is not seen for quite some
time, I hope someone can give a reply to the question of the thread.
Well, if you want to keep the variadicity of the operation, it's hardly
possible, because you can only return either a number or a function. In
lisp, numbers are not applicable functions.

Otherwise the following should work, in emacs-24:

;; in emacs-24:
(setq lexical-binding t)
(defun plus/2 (arg) (lambda (x) (+ arg x)))
(defun plus/3 (arg) (lambda (y) (plus/2 (funcall (plus/2 arg) y))))

(funcall (plus/2 2) 3) --> 5
(funcall (plus/3 2) 3) --> #<some closure>
(funcall (funcall (plus/3 2) 3) 4) --> 9
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Pascal J. Bourguignon
2012-10-23 08:15:07 UTC
Permalink
Post by Swami Tota Ram Shankar
Here are my questions.
Does setq cause some kind of permanent persistence of the variable
like a global?
In the lingo of computer science, such as lexical scoping, dynamic
scoping, static binding, dynamic binding, what is its meaning and what
is the meaning of these four terms?
See http://www.informatimago.com/articles/usenet.html#Variables
Post by Swami Tota Ram Shankar
I have found that let, and functional style leads to an onion type
structure.
f(g(h(x,y),z,k(alpha,beta,l(theta)))w)
If it is short, its not an issue, but the multiple cores or eyes of
the onion, makes it impossible to grasp the structure.
No, the issue is when it's short, with short, unmeaningful names.

If you use whole words and whole propositions as identifiers, then it
can read as English.

(mapcar (function list) (get-keys alist) (get-values alist))

vs.

(m (f l) (k a) (v a))
Post by Swami Tota Ram Shankar
I ask you to focus your brain intensely and come up with some
COMPELLING rules of thumb, so I can write programs that are readable.
Sorry, I don't have the time right now.
Post by Swami Tota Ram Shankar
I want to apply to my own thing, but you also tell us how to read
these programs since when I look at yours, it becomes digestable only
after persisting with it and going to the cores and reading inward
out.
The functions I presented you in this thread were procedural. You may
be confused because in lisp, scope is limited to parentheses too.

(when cond
expr1
expr2)

is different from:

(mapcar fun
expr1
expr2)

You have to read the operator first. That's why it's in the first
position in the lists: it's the most important thing you have to read to
understand lisp code. And that's why lisp operators are rarely cryptic
characters or single-letter. (The exceptions being +, -, *, etc, but
originally it was PLUS, MINUS, MULTIPLY, etc).

So when you read "when", you should know that it's a macro and that it
has some specific rules of evaluation of its arguments. You should then
read those arguments following those rules of evaluations. Namely, when
evaluates its first argument, and if it returns true, then it evaluates
in sequence the other arguments. This is not functional, this is
procedural!

On the other hand, when you read "mapcar", you should know that it's not
a macro or a special operator, so it's a function, and therefore all its
arguments are evaluated in order, and passed to the function that's
called last. Here you have an "onion", since you have to read inside
out to follow the flow of control.

But with macros and special operators, the flow of control can be
anything the macro is designed to implement. So you have to know your
macros and special operators.
Post by Swami Tota Ram Shankar
Whats your method or habit of reading?
Read the reference.

Common Lisp:
http://www.lispworks.com/documentation/HyperSpec/Front/index.htm


emacs lisp:
An Introduction to Programming in Emacs Lisp
http://www.gnu.org/software/emacs/emacs-lisp-intro/ or M-: (info "(eintr)Top") RET

Emacs Lisp Manual
http://www.gnu.org/software/emacs/manual/elisp.html or M-: (info "(elisp)Top") RET
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Continue reading on narkive:
Loading...