I'm new to Lisp, so I'm guessing I'm missing something simple here. I found some code online that I wanted to play with, and it uses the defgrammar macro. When I write it into my code file, copied exactly from the web to start with, save, and load, it says (with file name omitted):
;; Loading file ...
*** - EVAL: undefined function DEFGRAMMAR
I'm guessing there's some variable I have to flip, like for printing circular lists, or some add-on or something I have to install, but I don't really know what I'm looking for. Any suggestions?
By the way, I'm using GNU CLisp 2.49.
The code I'm trying to use is:
(load "rdp")
(use-package "COM.INFORMATIMAGO.RDP")
(defgrammar binary-tree
:terminals ((label "[^(),][^(),]*"))
:start tree
:rules ((--> tree
(opt node)
:action (if (null $1)
(make-empty-binary-tree)
$1)) ; it's identity, but make-empty-binary-tree
; could be defined otherwise.
(--> node
label (opt children)
:action (make-binary-tree :label (read-from-string (second $1))
:left (first $2) :right (second $2)))
(--> children
"(" tree "," tree ")"
:action (list $2 $4))))
(defun binary-tree-from-string (string)
(parse-binary-tree string))
Looking at it, I'm guessing I need "rdp"?
What's the code you want to play with, could you paste it here? defgrammar is not a built-in function. You should find the definition of defgrammar function. Load it first then re-evaluate your example.
Related
I am saving some commands in a Haskell script in a .hs file while working thru a Haskell textbook. Here's a small example.
fst (1,2)
snd (1,2)
When I run these commands from the prelude in GHCi, they work fine. When I try to compile the .hs file with these two lines, I get the following:
ch4_test.hs:2:1: error:
Parse error: module header, import declaration
or top-level declaration expected.
|
2 | fst (1,2)
| ^^^^^^^^^
Failed, no modules loaded.
I've googled this error and can't find any explanation what I'm doing wrong.
From a newbie to future newbies: The interactive environment ghci would lead you to believe that you can punch some expressions into an .hs file and run the thing (in a similar fashion to languages like swift and ruby). This is not the case.
Haskell needs an entrypoint called main. Quoting:
Here is a simple program to read and then print a character:
main :: IO ()
main = do c <- getChar
putChar c
The use of the name main is important: main is defined to be the entry point of a Haskell program (similar to the main function in C), and must have an IO type, usually IO ()
Source: https://www.haskell.org/tutorial/io.html
You can't just put any expression in a hs file.
As the error message says, you need a declaration here. For example:
main =
print (fst (1,2)) >>
print (snd (1,2))
I am getting this error but the cause appears to be completely different from anything posted here. And the error message is not at all helpful.
Using Cabal version 3.6.2.0 with GHCI 8.10.7 on MacOS High Sierra (10.13)
I'm working from this page: https://www.tutorialspoint.com/haskell/haskell_modules.htm
specifically the "custom modules" section. There you can see the code I copied and pasted.
Besides the tutorial not mentioning I needed to add "other-modules: Custom" to myfirstapp.cabal, and besides the fact that the sample Custom.hs file includes "if x 'rem' 2 == 0" rather than "if x rem 2 == 0", here is the problem:
Indentation matters!
This line (inside the quotes) does NOT work "if x rem 2 == 0".
This line DOES work " if x rem 2 == 0"!
Indenting by one space is the difference between success and failure.
I'm totally new to Haskell. I've programmed extensively in PHP, Javascript, and Applescript, and dabbled in a dozen others, and this is the first time I've seen white space matter. I assume this is commonly known amongst Haskell veterans, but it would certainly be nice if that was included prominently in the documentation.
I have a need to clean-up directory with millions of log files on my webserver. And I've found this great article on how to do this. There is, however, a couple interesting things in that one-liner, which I am interested in.
Here's the Perl code I am interested in:
for(<*>){((stat)[9]<(unlink))}
Runned with perl -e 'code'.
So, here are my questions:
the for(<*>) construction - I assume it iterates through the files in the current directory. But where does it store the iterator?
the stat and unlink functions expect at least one argument, I assume... But where is it?
why the result of calling (stat)[9] is compared to the result of calling (unlink)? And what does it results in?
Sorry, I am a no-perl-ish guy, thus I do not understand all those Perl abbreviations. That's why I am asking this question.
Thanks!
That one liner takes many shortcuts:
The <*> is a special case of the diamond operator. You can't access an iterator object, like in other languages. Here, it calls the glob function. In list context it returns a list from all the results (which are either lines of a file, or, as in your case, contents of a diretory. The return value of that is passed to for which iterates over a list and aliases the values in $_. $_ is the "default variable" for many functions…
Which brings us here. Many core functions default to $_ with no argument. So do unlink and stat.
(stat)[9] means execute stat in list context and select the 10th result (indices start at zero, this is the modify time). (compare that to an array access like $foo[9]).
The code
for(<*>){((stat)[9]<(unlink))}
is equivalent to:
for my $file (<*>) {
my $mtime = (stat($file))[9];
$mtime < unlink($file);
}
<*> can also be replaced with glob "*" which might be more readable.
The code will delete all files in the current directory. It will not delete directories.
Note that the last statement in the loop is completely redundant. If use warnings is in effect, it will give the warning:
Useless use of numeric lt (<) in void context
For this code to make sense, I would expect a comparison that actually matters, like comparing $mtime to some time to know which logs are old, e.g.:
if ($mtime < $oldtime) {
unlink $file or die "Cannot unlink $file: $!";
}
Note also that it might be prudent to check for failure when deleting files.
the for(<*>) construction - I assume it iterates through the files in the current directory. But where does it store the iterator?
for-loops can be used to iterate over arrays/lists, so if <*> produces a list, then your code is just a run of the mill for loop. As it turns out <*> is another way to spell glob(), which is sort of like a regex for retrieving file names, and glob() returns a list in list context--which is the context a for loop provides. See: http://perldoc.perl.org/functions/glob.html.
Note that the single quotes keep the shell from expanding the *, which would prevent perl from ever seeing it.
I am new to (Lisp) scheme programming and have been following the tutorial. Everything went well until I use string-set!
String-set! is use to replace the character at index. An example of what I did below:
Welcome to Racket v5.1.3.
> (define greeting "Hello; Hello!")
> (string-set! greeting 1 #\a)
string-set!: expects type <mutable string> as 1st argument, given: "Hello; Hello!"; other arguments were: 1 #\a
=== context ===
/usr/share/racket/collects/racket/private/misc.rkt:85:7
> greeting
"Hello; Hello!"
>
When (string-set! greeting 1 #\a) executed, it should replace the first 'e' to 'a' according to the tutorial. The output should be:
> greeting
"Hallo; Hello!"
But instead I am getting the error string-set!: expects type <mutable string> as 1st argument.
Am I doing it the wrong way?
As per the Racket documentation:
A string can be mutable or immutable. When an immutable string is provided to a procedure like string-set!, the exn:fail:contract exception is raised. String constants generated by the default reader (see Reading Strings) are immutable, and they are interned in read-syntax mode.
You can use string-copy to make a copy of a string, and this always returns a mutable string.
(define greeting (string-copy "Hello; Hello!"))
Your code is not suppose to work according to the R5RS or R6RS. It clearly states:
(define (g) "***")
(string-set! (g) 0 #\?) ===> error
It might be an error in your tutorial. You need to make the string mutable:
(define greeting (string-copy "Hello; Hello!"))
(string-set! greeting 1 #\a)
greeting ; ==> "Hallo; Hello!"
BTW: When you start Racket from command line or DrRacket in a windowed environment your are not expected to write Scheme, but a dialect that has diverged from the standard called racket. Most of Scheme will work though, but not set-car! or set-cdr!.
I advice you to use a Scheme standard according your tutorial. To use racket to run a Scheme standard from command line, you start either plt-r5rs or plt-r6rs. In DrRacket you can use choose language in the bottom left. Choose "Other > Legacy language R5RS" or select The racket language and start your definitions windows with:
#!r6rs
(import (rnrs))
DrRacket has a debugger so I recommend it. I googled your line and if you are following Teach Yourself Scheme in Fixnum Days, it conforms to the R5RS standard.
If you rather want to learn racket I recommend Realm of racket (2013) since you make games, which are fun. There is also a free book called How to design programs (2003).
I am new to elisp but I am trying to spice up my .emacs a little.
I am trying to define some paths, but having problems with creating a list of paths (and setting the list for YaSnippet more specifically).
When I evaluate the list I get a list of the symbol name (and not the symbol values as yassnippet want).
I got the code working but have feeling that there is a better way to do this?
Here is the working code:
;; some paths
(setq my-snippets-path "~/.emacs.d/snippets")
(setq default-snippets-path "~/.emacs.d/site-lisp/yasnippet/snippets")
;; set the yas/root-directory to a list of the paths
(setq yas/root-directory `(,my-snippets-path ,default-snippets-path))
;; load the directories
(mapc 'yas/load-directory yas/root-directory)
If you evaluate a list of strings, the result depends on the value of the list items. The best way to test that is to launch the ielm repl (M-x ielm), and enter:
ELISP> '("abc" "def" "ghi")
("abc" "def" "ghi")
The quoted list of string evaluates to the list value. If you store the value of the list in a variable, and then evaluate the variable, ELisp will complain that the function abc is unknown.
ELISP> (setq my-list '("abc" "def" "ghi"))
("abc" "def" "ghi")
ELISP> (eval my-list)
*** Eval error *** Invalid function: "abc"
For the yasnippet directory configuration, you should just set yas-snippet-dir instead, e.g.
(add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet")
(require 'yasnippet)
(setq yas-snippet-dirs
'("~/.emacs.d/snippets" ;; personal snippets
"/path/to/yasnippet/snippets" ;; the default collection
"/path/to/other/snippets" ;; add any other folder with a snippet collection
))
(yas-global-mode 1)
Edit:
The use of yas/root-directory has been deprecated. From the documentation of yasnippet.el
`yas-snippet-dirs'
The directory where user-created snippets are to be
stored. Can also be a list of directories. In that case,
when used for bulk (re)loading of snippets (at startup or
via `yas-reload-all'), directories appearing earlier in
the list shadow other dir's snippets. Also, the first
directory is taken as the default for storing the user's
new snippets.
The deprecated `yas/root-directory' aliases this variable
for backward-compatibility.
I think you want
(setq yas/root-directory (list my-snippets-path default-snippets-path))
I have seen a lot of C/C++ based solutions to this problem where we have to write a program that upon execution prints its own source.
some solutions --
http://www.cprogramming.com/challenges/solutions/self_print.html
Quine Page solution in many languages
There are many more solutions on the net, each different from the other. I wonder how do we approach to such a problem, what goes inside the mind of the one who solves it. Lend me some insights into this problem... While solutions in interpreted languages like perl, php, ruby, etc might be easy... i would like to know how does one go about designing it in compiled languages...
Aside from cheating¹ there is no difference between compiled and interpreted languages.
The generic approach to quines is quite easy. First, whatever the program looks like, at some point it has to print something:
print ...
However, what should it print? Itself. So it needs to print the "print" command:
print "print ..."
What should it print next? Well, in the mean time the program grew, so it needs to print the string starting with "print", too:
print "print \"print ...\""
Now the program grew again, so there's again more to print:
print "print \"print \\\"...\\\"\""
And so on.
With every added code there's more code to print.
This approach is getting nowhere,
but it reveals an interesting pattern:
The string "print \"" is repeated over and over again.
It would be nice to put the repeating part
into a variable:
a = "print \""
print a
However, the program just changed,
so we need to adjust a:
a = "a = ...\nprint a"
print a
When we now try to fill in the "...",
we run into the same problems as before.
Ultimately, we want to write something like this:
a = "a = " + (quoted contents of a) + "\nprint a"
print a
But that is not possible,
because even if we had such a function quoted() for quoting,
there's still the problem that we define a in terms of itself:
a = "a = " + quoted(a) + "\nprint a"
print a
So the only thing we can do is putting a place holder into a:
a = "a = #\nprint a"
print a
And that's the whole trick!
Anything else is now clear.
Simply replace the place holder
with the quoted contents of a:
a = "a = #\nprint a"
print a.replace("#", quoted(a))
Since we have changed the code,
we need to adjust the string:
a = "a = #\nprint a.replace(\"#\", quoted(a))"
print a.replace("#", quoted(a))
And that's it!
All quines in all languages work that way
(except the cheating ones).
Well, you should ensure that you replace only
the first occurence of the place holder.
And if you use a second place holder,
you can avoid needing to quote the string.
But those are minor issues
and easy to solve.
If fact, the realization of quoted() and replace()
are the only details in which the various quines really differ.
¹ by making the program read its source file
There are a couple of different strategies to writing quines. The obvious one is to just write code that opens the code and prints it out. But the more interesting ones involve language features that allow for self-embedding, like the %s-style printf feature in many languages. You have to figure out how to embed something so that it ends up resolving to the request to be embedded. I suspect, like palindromes, a lot of trial and error is involved.
The usual approach (when you can't cheat*) is to write something that encodes its source in a string constant, then prints out that constant twice: Once as a string literal, and once as code. That gets around the "every time I write a line of code, I have to write another to print it out!" problem.
'Cheating' includes:
- Using an interpreted language and simply loading the source and printing it
- 0-byte long files, which are valid in some languages, such as C.
For fun, I came up with one in Scheme, which I was pretty proud of for about 5 minutes until I discovered has been discovered before. Anyways, there's a slight modification to the "rules" of the game to better count for the duality of data and code in Lisp: instead of printing out the source of the program, it's an S-expression that returns itself:
((lambda (x) (list x `',x)) '(lambda (x) (list x `',x)))
The one on Wikipedia has the same concept, but with a slightly different (more verbose) mechanism for quoting. I like mine better though.
One idea to think about encoding and how to give something a double meaning so that it can be used to output something in a couple of forms. There is also the cavaet that this type of problem comes with restrictions to make it harder as without any rules other than the program output itself, the empty program is a solution.
How about actually reading and printing your source code? Its not difficult at all!! Heres one in php:
<?php
{
header("Content-Type: text/plain");
$f=fopen("5.php","r");
while(!feof($f))
{
echo fgetc($f);
}
fclose($f);
}
?>
In python, you can write:
s='c=chr(39);print"s="+c+s+c+";"+s';c=chr(39);print"s="+c+s+c+";"+s
inspired from this self printing pseudo-code:
Print the following line twice, the second time with quotes.
"Print the following line twice, the second time with quotes."
I've done a AS3 example for those interested in this
var program = "var program = #; function main(){trace(program.replace('#',
String.fromCharCode(34) + program + String.fromCharCode(34)))} main()";
function main(){
trace(program.replace('#', String.fromCharCode(34) + program + String.fromCharCode(34)))
}
main()
In bash it is really easy
touch test; chmod oug+x test; ./test
Empty file, Empty output
In ruby:
puts File.read(_ _ FILE _ _)