Here is my MIT Scheme code:
(display (name->package '(user)))
(newline)
(->environment (name->package '(user)))
(%exit)
This runs fine on MIT/GNU Scheme Release 9.1.1. Here is the output:
$ scheme --quiet --load foo.scm
#[package 13 (user)]
But when I run this with MIT/GNU Scheme Release 10.1.5, I get this error:
$ mit-scheme --quiet --load foo.scm
#[package 12 (user)]
;The object #[package 12 (user)], passed as an argument to ->environment, is not an environment.
;To continue, call RESTART with an option number:
; (RESTART 1) => Return to read-eval-print level 1.
2 error>
On debugging I get this,
2 error> (debug)
There are 7 subproblems on the stack.
Subproblem level: 0 (this is the lowest subproblem level)
Compiled code expression unknown
#[compiled-return-address 13 ("rep" #x2f) #xd8 #x95ed10]
There is no current environment.
There is no execution history for this subproblem.
You are now in the debugger. Type q to quit, ? for commands.
3 debug>
Why does this error occur in 10.1.5 but not in 9.1.1?
Related
I recently decided to start playing with MIT Scheme by following along with the examples in SICP. I installed scheme from the Ubuntu repository.
sudo apt-get install mit-scheme
Given an input file that looks like this:
486
(+ 137 349)
(- 1000 334)
(* 5 99)
(/ 10 5)
(* 25 4 12)
I run scheme as follows.
scheme < Numbers.scm
It produces the following output.
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2011 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Sunday February 7, 2016 at 10:35:34 AM
Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118 || Edwin 3.116
1 ]=> 486
;Value: 486
1 ]=> (+ 137 349)
;Value: 486
1 ]=> (- 1000 334)
;Value: 666
1 ]=> (* 5 99)
;Value: 495
1 ]=> (/ 10 5)
;Value: 2
1 ]=> (* 25 4 12)
;Value: 1200
1 ]=>
End of input stream reached.
Moriturus te saluto.
This output feels excessive, so I'm currently paring it down like so.
scheme < Numbers.scm | awk '/Value/ {print $2}
486
486
666
495
2
1200
Is there a native way to reduce the verbosity of scheme, so I can get something resembling the above output without resorting to an external process?
I have examined the output of scheme --help but did not find any obvious options.
Note that passing the filename as an argument does not appear to work in MIT-Scheme.
scheme Numbers.scm
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2011 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Sunday February 7, 2016 at 10:35:34 AM
Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118 || Edwin 3.116
;Warning: Invalid keyword: "Numbers.scm"
;Warning: Unhandled command line options: ("Numbers.scm")
1 ]=>
Here you go:
scheme --quiet < Numbers.scm
Now this will suppress the REPL entirely except when errors occur so that what is not explicitly displayed will not be displayed. eg. evaluatiing (+ 2 3) returns 5, but does not print since you have not told it to print. You need to use procedures like display to get the information printed or go back to using a REPL which sole purpose is to display your results.
I was originally hoping you could do:
scheme --quiet --load Numbers.scm
But it does not exit after the file and adding --eval (exit) has the REPL ask if you want to quit.
EDIT
(define (displayln v)
(display v)
(newline)
v)
(displayln (+ 4 5))
; ==> 9, in addition you get the side effect that "9\n" is written to current output port
You could also perhaps make a macro to do this:
(define-syntax begin-display
(syntax-rules ()
((_ form ...) (begin (displayln form) ...))))
(begin-display
486
(+ 137 349)
(- 1000 334)
(* 5 99)
(/ 10 5)
(* 25 4 12))
; ==> 1200. In addition you get the side effect that "486\n486\n666\n49\n2\n1200\n" is written to current output port
As a workaround,
scheme < Numbers.scm | gawk '/^;Value: / { sub(/^;Value: /, ""); print }'
But maybe you'd run it as a script file rather than an stdin stream? Not sure about MIT Scheme invocation, something like
scheme Numbers.scm
Though this way you'll have to print out the results explicitly, with (display) or something, otherwise they'll go unnoticed.
I write a makefile for my erlang project and it works. But while project is running, if i change a file and make it by makefile, the new version of code not works and i must exit shell and start it again to run the new version. How can solve it?
makefile:
# Makefile
SRC_DIR = src
BIN_DIR = ebin
DB_DIR = db
ERL = erl
ERLC = erlc
ERLC_FLAGS=
SOURCES=$(wildcard ${SRC_DIR}/*.erl)
HEADERS=$(wildcard ${SRC_DIR}/*.hrl)
OBJECTS=$(SOURCES:${SRC_DIR}/%.erl=${BIN_DIR}/%.beam)
all: $(OBJECTS)
ebin/%.beam : src/%.erl $(HEADERS) Makefile
${ERLC} $(ERLC_FLAGS) -o ${BIN_DIR}/ $<
drop_db:
rm -r ${DB_DIR}
clean:
-rm $(OBJECTS)
run:
${ERL} -pa ${BIN_DIR} -s god run
Erlang allows to modify the application code in run easily, but it doesn't mean that it is transparent to the user.
Hopefully it isn't transparent, otherwise the feature couldn't be used, or only restricted to trivial use cases. Here are the first 3 reasons that come to my mind to justify that code change must be under the user responsibility and control:
from one version to another one, the data may need to be adapted (modified record, modified structure, new data ...). So on transition, the new version of code must update the state data; it even must verify that it is able to do it (does it have the transformation code to go from version X to version Y). The OTP behaviors provides special callback for this.
An application modification may involve changes in multiple modules, and a module may be run by many processes (a web client for example). But the code is updated at the process level at very specific time (fully qualified call) and it cannot occur for all processes simultaneously. So you must control the order of module upgrade. The function code:load_file(Module) allows this.
Only (:o) 2 versions of a module may live concurrently in one node. If you run a module and then make 2 modifications loading the module twice, the oldest code "disappears" and any process still using this version simply dies. You need to synchronize the upgrade. The function code:soft_purge(Module) helps you for this.
After all this warnings come back to the fun. You can easily play with code upgrade to get more familiar with it. Only 2 steps and one condition are required:
the new beam file (compiled code) must be in the code path of your Erlang VM (or you will have to use code:load_abs(Filename) in the next step).
You must load the new code in the VM. If you compile the code from the shell using c(my_module). it is done automatically. If you compile it by other means, you will have to explicitly load the new code in the VM using for example code:load_file(my_module).
Then you must ensure that each process using this module performs a fully qualified call to an exported function and thats it, for example: my_module:code_change(State). if you use OTP behavior, this callback exists and provide you also the old version of the code in parameter.
Lets use the following module:
-module(one).
-compile([export_all]).
-define (VERSION,1).
start() ->
rserver,spawn(?MODULE,init,[]).
init() ->
loop(0).
loop(N) ->
receive
print ->
io:format("received ~p message(s) so far~n",[N+1]),
loop(N+1);
load ->
io:format("received ~p message(s) so far~n reload the code~n",[N+1]),
?MODULE:loop(N+1);
version ->
io:format("received ~p message(s) so far~n version is ~p~n",[N+1,?VERSION]),
loop(N+1);
M ->
io:format("received unexpected message ~p: ignored~n",[M]),
loop(N)
end.
I compile it in the shell, start 2 processes and play with them:
1> c(one).
{ok,one}
2> P1 = one:start().
<0.40.0>
3> P2 = one:start().
<0.42.0>
4> P1 ! print.
received 1 message(s) so far
print
5> P1 ! print.
received 2 message(s) so far
print
6> P1 ! version.
received 3 message(s) so far
version is 1
version
7> P1 ! reset.
received unexpected message reset: ignored
reset
8> P2 ! print.
received 1 message(s) so far
print
9>
Now I modify the code to:
-module(one).
-compile([export_all]).
-define (VERSION,2).
start() ->
rserver,spawn(?MODULE,init,[]).
init() ->
loop(0).
loop(N) ->
receive
print ->
io:format("received ~p message(s) so far~n",[N+1]),
loop(N+1);
load ->
io:format("received ~p message(s) so far~n reload the code~n",[N+1]),
?MODULE:loop(N+1);
version ->
io:format("received ~p message(s) so far~n version is ~p~n",[N+1,?VERSION]),
loop(N+1);
reset ->
io:format("received ~p message(s) so far, reset message count~n",[N+1]),
loop(0);
M ->
io:format("received unexpected message ~p: ignored~n",[M]),
loop(N)
end.
Compile it outside the VM and test:
9> P1 ! version.
received 4 message(s) so far
version is 1
version
10> P1 ! load.
received 5 message(s) so far
reload the code
load
11> P1 ! version.
received 6 message(s) so far
version is 1
version
12> P1 ! reset.
received unexpected message reset: ignored
reset
13> P2 ! print.
received 2 message(s) so far
print
14>
As I didn't load the code, there is no update: the VM will not loose time to search in the code path if a new version exists at each external call!
14> code:load_file(one).
{module,one}
15> P1 ! version.
received 7 message(s) so far
version is 1
version
16> P2 ! version.
received 3 message(s) so far
version is 1
version
17> P1 ! load.
received 8 message(s) so far
reload the code
load
18> P1 ! version.
received 9 message(s) so far
version is 2
version
19> P1 ! reset.
received 10 message(s) so far, reset message count
reset
20> P1 ! print.
received 1 message(s) so far
print
21> P2 ! version.
received 4 message(s) so far
version is 1
version
22> P2 ! print.
received 5 message(s) so far
print
23>
after loading the new code, I have been able to upgrade the version of P1, while P2 is still on version 1.
Now I make a new modification, simply going to version 3 and compile in in the shell to force the code loading:
23> c(one).
{ok,one}
24> P1 ! version.
received 2 message(s) so far
version is 2
version
25> P1 ! load.
received 3 message(s) so far
reload the code
load
26> P1 ! version.
received 4 message(s) so far
version is 3
version
27> P2 ! print.
print
28>
I have been able tu upgrade the process P1 from version 2 to 3. But the process P2 which was still using the version 1 is died.
I want to programing a function about open the file directly. Like python code:
os.system("ls")
For example, when I use this function (fun_open "/path/to/file"), the system will open the file use the default app. If file is a .txt, open it with textedit.
How to make it?
----UPDATE 9/24/2015-----
My code is:
(defun open_by_system (dir)
(sb-ext:run-program "/usr/bin/open" (list "-a" "Preview" dir)))
and I use it:
CL-USER> (open_by_system "~/Desktop/ML.pdf")
#<SB-IMPL::PROCESS :EXITED 1>
Nothing else happen
I'd recommend using UIOP, which provides portable interface to the OS and is universally available as a part of ASDF3:
(uiop:run-program "ls")
See the docstrings in run-program.lisp for details.
If you need more convenience functions, you could take a look at inferior-shell.
I recommend you to take a look at the available libraries on quickdocs:
link
I recommend you to use inferior-shell available on quicklisp
link
loading:
CL-USER> (ql:quickload 'inferior-shell)
To load "inferior-shell":
Load 5 ASDF systems:
alexandria asdf closer-mop named-readtables optima
Install 4 Quicklisp releases:
fare-mop fare-quasiquote fare-utils inferior-shell
; Fetching #<URL "http://beta.quicklisp.org/archive/fare-quasiquote/2015-06-08/fare-quasiquote-20150608-git.tgz">
; 15.08KB
==================================================
15,437 bytes in 0.10 seconds (157.03KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/fare-utils/2015-06-08/fare-utils-20150608-git.tgz">
; 31.51KB
==================================================
32,264 bytes in 0.14 seconds (218.80KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/fare-mop/2015-06-08/fare-mop-20150608-git.tgz">
; 2.67KB
==================================================
2,738 bytes in 0.00 seconds (0.00KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/archive/inferior-shell/2015-06-08/inferior-shell-20150608-git.tgz">
; 12.87KB
==================================================
13,182 bytes in 0.00 seconds (12873.05KB/sec)
; Loading "inferior-shell"
[package fare-utils]..............................
[package fare-stateful]...........................
[package fare-quasiquote].........................
[package fare-mop].............
(INFERIOR-SHELL)
a simple sample:
CL-USER> (inferior-shell:run/ss '(echo (1) "2" (+ 3)))
"1 2 3"
NIL
0
a sample with pipes:
CL-USER> (inferior-shell:run/ss `(inferior-shell:pipe (echo (+ hel "lo,") world) (tr "hw" "HW") (sed -e "s/$/!/")))
"Hello, World!"
NIL
0
Mac OS X and SBCL:
Open a text file in the default text editor application TextEdit:
Lisp Machine:~ lispm$ touch /tmp/test.text
Lisp Machine:~ lispm$ sbcl
This is SBCL 1.2.14, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (sb-ext:run-program "/usr/bin/open" '("/tmp/test.text"))
#<SB-IMPL::PROCESS :EXITED 0>
Open the file with LispWorks as the text editor:
* (sb-ext:run-program
"/usr/bin/open"
'("-a"
"/Applications/LispWorks 7.0 (64-bit)/LispWorks (64-bit).app"
"/tmp/test.text"))
You might want to consult the SBCL manual for such questions. For example the chapter on Running External Programs.
In clisp, the following code works:
(defun hit-history () (shell "tail ssqHitNum.txt"))
However, in Clozure CL, the shell function is not supported!
No, there is no standard way, but there are libraries which provide this functionality for the important implementations. For example, there's trivial-shell available in Quicklisp, which provides shell-command. (I didn't actually test it, but its among the recommended libraries on CLiki.) There is also external-program. Update: inferior-shell seems to be prefered these days, as Ehvince points out in a comment and his own answer.
You could also use read-time conditionals to make different implementations use their respective functionality to do this.
CCL has ccl:run-program, for example:
CL-USER> (run-program "whoami" '() :output *standard-output*)
foobar
#<EXTERNAL-PROCESS (whoami)[NIL] (EXITED : 0) #xC695EA6>
Yes, with UIOP, part of ASDF, that should be included in all modern implementations.
synchronous commands: uiop:run-program
asynchronous commands: uiop:launch-program
So for example
(uiop:run-program (list "firefox" "http:url") :output t)
or
(defparameter *shell* (uiop:launch-program "bash" :input :stream :output :stream))
where you can send input and read output.
They are more explained here: https://lispcookbook.github.io/cl-cookbook/os.html#running-external-programs
trivial-shell is deprecated and replaced by inferior-shell, which internally uses the portable uiop's run-program (synchronous), so we can use just that.
(defun dot->png (fname thunk)
(with-open-file (*standard-output*
fname
:direction :output
:if-exists :superseded)
(funcall thunk))
(ccl:run-program "dot" (list "-Tpng -O" fname))
)
i run success in ccl(clozure),when study land of lisp p123
The following shows an example of calling wget from within common lisp:
https://diasp.eu/posts/1742240
Here's the code:
(sb-ext:run-program "/usr/bin/wget" '("-O" "<path-to-output-file>" "<url-link>") :output *standard-output*)
Have a look at the inferior-shell package.
(Get it via the almighty quicklisp package manager.)
This works in the interpreter, if you have internet:
(require 'inferior-shell)
(inferior-shell:run/s '(curl icanhazip.com))
CL21 defines simple methods:
(in-package :cl21-user)
(use-package :cl21.process)
Then either with run-process or with the #` reader macro:
(run-process '("ls" "-l"))
;-> total 0
; drwxrwxrwt 5 root wheel 170 Nov 1 18:00 Shared
; drwxr-xr-x+ 174 nitro_idiot staff 5916 Mar 5 21:41 nitro_idiot
;=> #<PROCESS /bin/sh -c ls -l /Users (76468) EXITED 0>
or
#`ls -l /Users`
;=> "total 0
; drwxrwxrwt 5 root wheel 170 Nov 1 18:00 Shared
; drwxr-xr-x+ 174 nitro_idiot staff 5916 Mar 5 21:41 nitro_idiot
; "
; ""
; 0
The source shows implementation for SBCL and CCL.
http://cl21.org/
https://github.com/cl21/cl21/wiki
https://lispcookbook.github.io/cl-cookbook/cl21.html
I installed Linpack on a 2-Node cluster with Xeon processors. Sometimes if I start Linpack with this command:
mpiexec -np 28 -print-rank-map -f /root/machines.HOSTS ./xhpl_intel64
linpack starts and prints the output, sometimes I only see the mpi mappings printed and then nothing following. To me this seems like random behaviour because I don't change anything between the calls and as already mentioned, Linpack sometimes starts, sometimes not.
In top I can see that xhpl_intel64processes have been created and they are heavily using the CPU but when watching the traffic between the nodes, iftop is telling me that it nothing is sent.
I am using MPICH2 as MPI implementation. This is my HPL.dat:
# cat HPL.dat
HPLinpack benchmark input file
Innovative Computing Laboratory, University of Tennessee
HPL.out output file name (if any)
6 device out (6=stdout,7=stderr,file)
1 # of problems sizes (N)
10000 Ns
1 # of NBs
250 NBs
0 PMAP process mapping (0=Row-,1=Column-major)
1 # of process grids (P x Q)
2 Ps
14 Qs
16.0 threshold
1 # of panel fact
2 PFACTs (0=left, 1=Crout, 2=Right)
1 # of recursive stopping criterium
4 NBMINs (>= 1)
1 # of panels in recursion
2 NDIVs
1 # of recursive panel fact.
1 RFACTs (0=left, 1=Crout, 2=Right)
1 # of broadcast
1 BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
1 # of lookahead depth
1 DEPTHs (>=0)
2 SWAP (0=bin-exch,1=long,2=mix)
64 swapping threshold
0 L1 in (0=transposed,1=no-transposed) form
0 U in (0=transposed,1=no-transposed) form
1 Equilibration (0=no,1=yes)
8 memory alignment in double (> 0)
edit2:
I now just let the program run for a while and after 30min it tells me:
# mpiexec -np 32 -print-rank-map -f /root/machines.HOSTS ./xhpl_intel64
(node-0:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
(node-1:16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31)
Assertion failed in file ../../socksm.c at line 2577: (it_plfd->revents & 0x008) == 0
internal ABORT - process 0
APPLICATION TERMINATED WITH THE EXIT STRING: Hangup (signal 1)
Is this a mpi problem?
Do you know what type of problem this could be?
I figured out what the problem was: MPICH2 uses different random ports each time it starts and if these are blocked your application wont start up correctly.
The solution for MPICH2 is to set the environment variable MPICH_PORT_RANGE to START:END, like this:
export MPICH_PORT_RANGE=50000:51000
Best,
heinrich