I am getting started with LISP and write the following program
(write-line "hello world")
(print "hello world print")
(write "hello world write")
for which I get the following output
hello world
"hello world print" "hello world write"
I guess write and print return string object so whats the type thats being returned by write-line why this didn't have quotations.
Link to my work-space
According to write-line/ write-string official documentation it returns its argument. What you see it the side effect (printing). Usually you will also see the return if top level in a REPL:
> (write-line "hello world")
; hello world (printed)
;==> "hello world" (returned)
Note that write is not limited to printing strings as they take any CL object and prin1, print, pprint, and princ are just write with some dynamic settings predefined.
Related
Really hoping someone can help me to understand this behavior and how to work around it.
> functions hello
# Defined in ...
function hello
echo -n $argv[1] "hello"
end
> functions world
# Defined in ...
function world
echo -n "world"
end
> hello
hello⏎
> world
world⏎
> world | hello
hello⏎
You have misunderstood how the $argv function local variable is initialized. It is not set to the contents of stdin. It is set to the positional arguments of the function. For example, hello (world) will produce the output you expect. If you want your edit function to capture its data from stdin you need to explicitly read stdin.
As #Kurtis-Rader's answer mentioned, to access a pipe in a fish function, you use the read command (see man read). This is similar to bash, sh, zsh, etc.
Example for fish (with edits discussed in the comments to make the piped input optional):
function greeting
echo "Good Morning"
end
function world
if isatty stdin
set greetstring "Hello"
else
read greetstring
end
echo (string trim $greetstring)", World"
end
> greeting | world
Good Morning, World
> world
Hello, World
To read multiline input from a pipe, you wrap the read in a while statement.
I write emacs lisp code as follows:
#!/usr/bin/emacs --script
(setq input (read-minibuffer "please input your name:") )
(message "%s" input)
and then I use this code to test standard input:
./test.el
please input your name:hello
hello
this is ok for the first test. But when I put string hello,world to standard input, it occurs error:
please input your name:hello,world
Trailing garbage following expression
And then I put string "hello,world" to standard input, it passed:
please input your name:"hello,world"
hello,world
Then I want to know, how should I do that can get the input string without "
punctuation. I just want to input hello,world, rather then "hello,world".
Thanks
The function read-minibuffer expects the user to input a Lisp object. If you enter hello, it returns a symbol, and if you enter "hello,world", it returns a string.
You probably want the function read-from-minibuffer instead. It returns what the user entered as a string, without trying to interpret it in any way.
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'm trying to do something like this:
* Define some functions
#+begin_src python :noweb_ref defs
def f1(a,b,c):
return True
def f2(d,e,f):
return False
#+end_src
* Use them in a results-exported block later
#+begin_src python :results output :exports both :tangle yes
<<defs>>
print "test results:"
print f1(1,2,3)
#end_src
What I want to happen is for <<defs>> to be expanded tangle-style when the block is evaluated to produce the export output. What actually happens is that <<defs>> gets evaluated literally and causes a syntax error.
When tangling blocks like this to an output file, everything works perfectly, but I can't figure out how to do the same thing when I'm exporting the buffer.
Suggestions?
I'm not sure to really understand your point... but
1) you miss a noweb:yes header argument
2) you can use <<func()>> to insert the results of evaluating func (instead of the code of func) -- that's here that I'm not sure about what you really want.
You can also use :noweb no-export. That shows the noweb-syntax in exported files but expands the code blocks when evaluating or tangling the files.
:noweb strip-export is great if you just want to show an algorithm:
<<prep>>
result = A + B
<<plot>>
The exported file then shows this:
result = A + B
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