I begin to learn newlisp, but the quote and ' puzzle me.
> (= '(quote 1) ''1)
nil
or
> (first (quote (quote 1)))
quote
> (first ''1)
ERR: array, list or string expected in function first : ''1
in newlisp, quote is different from ' ?
or, this is a bug?
There is a subtle difference between the two. The single quote is resolved during source code translation, when the quoted cell is wrapped into a protecting envelope. The function quote does the same but during evaluation. For most purposes they behave in the same way.
So the function quote is more like the original Lisp quote. The ' is an optimization performed during code translation. If you want to know more about code translation and evaluation, compare the functions read-expr and eval-string.
Related
I am trying to read the board from a text file, but while printing it is also printing the newline and inverted commas as:
(with-open-file (stream "brd1.txt")
(do ((line (read-line stream nil)
(read-line stream nil)))
((null line))
(print line)))
"+ + +^M"
" 3 3 ^M"
"+ + +^M"
" ^M"
"+ + +"
NIL
I am new to LISP. Could somebody help me to format these lines to print the exact board as:
+ + +
3 3
+ + +
+ + +
Input
Apparently you're trying to feed a DOS text file with CRLF-delimited lines to a Lisp implementation that assumes the lines to be LF-delimited in the Unix fashion. Note that read-line strips the newlines, so in our case LF's are stripped, but CR's are treated as ordinary characters and thus remain in the string.
Newlines are platform specific and hence implementation dependent in Lisp. What's more, it seems that neither asdf nor asdf-encodings address this issue. The way I see it you have the following options:
trim the CR's manually e. g. like this:
(string-right-trim '(\#Return) line)
use one of asdf's functions slurp-stream-string and slurp-stream-lines;
use some implementation specific mechanism to specify the encoding;
convert your text file to the Unix format.
Output
As already noted, PRINT is actually a human-readable serialisation. There is a bunch of printing functions on CLHS's page for WRITE and, of course, FORMAT. In order to output a string you can also use WRITE-STRING (without appending a newline) or WRITE-LINE (with a newline).
UPD
Actually UIOP (not ASDF!) exports the utility function UIOP:STRIPLN, which does the following, according to its docstring:
"Strip a string X from any ending CR, LF or CRLF.
Return two values, the stripped string and the ending that was stripped,
or the original value and NIL if no stripping took place.
Since our STRCAT accepts NIL as empty string designator,
the two results passed to STRCAT always reconstitute the original string"
As you can see from the documentation, print "produces output suitable for input to read". Use format instead:
(format t "~a" line)
I have a statement which currently looks like this:
arrays.foldLeft(0)((offset, array) => array.copyTo(largerArray, offset))
It would be great to express it as follows, but this is not possible since foldLeft is designed to take the seed argument first:
arrays.foldLeft(0)(_.copyTo(largerArray, _))
This is purely superficial - I'm just curious!
p.s. copyTo returns the next offset in this example.
The SLS seems to say "no".
Section 6.23, Anonymous Functions/Placeholder Syntax for Anonymous Functions:
An expression (of syntactic category Expr) may contain embedded
underscore symbols _ at places where identifiers are legal. Such an
expression represents an anonymous function where subsequent
occurrences of underscores denote successive parameters.
and
If an expression e binds underscore sections u1 , . . . , un, in this order, it is equivalent to the anonymous function (u'1 , ... u'n ) => e' where each u'i results from ui by replacing the
underscore with a fresh identifier and e' results from e by
replacing each underscore section ui by u'i.
Emphasis is mine - it explicitly states in both relevant section that a preserved ordering is assumed.
Personally, I think it makes sense to enforce that, if "only" for readability reasons.
When I have a string like "Test.m", how can I get just the substring "Test" from that via elisp? I'm trying to use this in my .emacs file.
One way is to use substring (or substring-no-properties):
(substring "Test.m" 0 -2) => "Test"
(substring STRING FROM &optional TO )
Return a new string whose contents are a substring of STRING. The
returned string consists of the characters between index FROM
(inclusive) and index TO (exclusive) of STRING. FROM and TO are
zero-indexed: 0 means the first character of STRING. Negative values
are counted from the end of STRING. If TO is nil, the substring runs
to the end of STRING.
Stefan's answer is idiomatic, when you just need a filename without extension. However, if you manipulate files and filepaths heavily in your code, i recommend installing Johan Andersson's f.el file and directory API, because it provides many functions absent in Emacs with a consistent API. Check out functions f-base and f-no-ext:
(f-base "~/doc/index.org") ; => "index"
(f-no-ext "~/doc/index.org") ; => "~/doc/index"
If, instead, you work with strings often, install Magnar Sveen's s.el for the same reasons. You might be interested in s-chop-suffix:
(s-chop-suffix ".org" "~/doc/index.org") ; => "~/doc/index"
For generic substring retrieval use dkim's answer.
In your particular case, you might like to use file-name-sans-extension.
Probably the most flexible option (although it's not clear if you need flexibility) would be to use replace-regexp-in-string:
See C-hf replace-regexp-in-string RET
e.g.:
(replace-regexp-in-string "\\..*" "" "Test.m")
Recently I was writing a little CLI script which needed to repeatedly read dates from the console (the number of dates to read was calculated and could be different each time). Sample Ruby code to give you the idea:
dates = x.times.collect { print "Enter date: "; Date.parse(gets.chomp) }
Just for the heck of it, I wrote the script in Clojure, and wound up using some rather ugly code with swap! and loop...recur. I'm wondering what the cleanest way to achieve the desired effect in Clojure would be. (Clojure does have dotimes, but it doesn't retain the values returned from evaluating the body... as might be expected from a language which emphasizes pure functional programming.)
read-line returns nil when the end of file is reached. On the console that is when you press CTRL-d (CTRL-z on Windows).
You could use this code to take advantage of this:
(doseq [line (repeatedly read-line) :while line]
(do-something-with line))
If you must read a fixed number of lines you can use:
(repeatedly n read-line)
If your goal is to end up with a sequence of exactly x dates entered by user then:
(for [line (repeatedly x read-line)] (DateFormat/parse line))
or using map:
(map DateFormat/parse (repeatedly x read-line))
Beware of lazy sequences in Clojure: user will be asked to enter more dates as they are needed. If your goal is for user to enter all dates at once (say at startup) then use doall:
(map DateFormat/parse (doall (repeatedly x read-line)))
This will read all dates at once, but will parse them lazily still, so date format validation could fail much later in your program. You can move doall one level up to parse promptly as well:
(doall (map DateFormat/parse (repeatedly x read-line)))
And you can use a helper function to read line with prompt:
(defn read-line-with-prompt [prompt]
(print prompt)
(read-line))
Then replace read-line with either:
#(read-line-with-prompt "Enter date: ")
or
(partial read-line-with-prompt "Enter date: ")
You can do something like this:
(defn read-dates [n]
(doall (for [_ (range n)] (java.util.Date/parse (read-line)))))
(def my-dates (read-dates 5)) ;Read 5 dates from console
(or (parse-integer (prompt-read "Rating") :junk-allowed t) 0)
This line confuses me quite a bit. the full program is here if you need it to follow: http://paste.lisp.org/display/124929
'Parse-integer' will turn a string into and integer right? if possible. And ':junk-allowed t' makes it accept junk strings somehow right?
Not sure what the 'or' and the 0 at the end are though.
Thanks.
or goes through the forms passed to it, evaluates them in order until it finds one that does not evaluate to nil, and returns that result. So this will return the result of parse-integer if that call succeeds in parsing an integer, or 0 if not.