Why am I getting lifted/5.1 undefined error while using formlets? - undefined

I am having trouble with an error I keep getting while trying to use formlets in racket. It says:
; lifted/5.1: undefined;
; cannot reference an identifier before its definition
; in module: top-level
; internal name: lifted/5.1
Nothing in my code is named "lifted" or "5.1" or any combination of the two. I am thinking that this is something inside the black box of formlets that I'm running up against, but I don't know what.
; set up
(require web-server/servlet web-server/servlet-env)
(require web-server/formlets)
; body of program
(define simpleformlet
(formlet
(#%#
"Name: " ,{input-string . => . name}
"Number: " ,{input-int . => . number})
(name number)))
(define (start request)
(showpage request))
(define (showpage request)
(define (responsegen embed/url)
(response/xexpr
`(html
(head (title "App3"))
(body (h1 "Let's try this...")
(form
([action ,(embed/url actionhandler)]
[method "POST"])
,#(formlet-display simpleformlet)
(input ([type "submit"])))))))
(define (actionhandler request)
(define-values (name number)
(formlet-process simpleformlet request))
(response/xexpr
`(html
(head (title "Alright!"))
(body (h2 "name")
(p ,name)
(h2 "number")
(p ,number)))))
(send/suspend/dispatch responsegen))
; run it!
(serve/servlet start
#:servlet-regexp #rx""
#:servlet-path "/form")

I added the line
#lang racket
at the top of your program. Used "Determine language from source" in the lower, left corner of DrRacket. And ran your program. A browser window opened and I was able to enter a name and a number, before I got a sensible error.
I am using Racket version 6.12, so if you are using an older version of Racket, then upgrade and try again.

Related

LISP: how to properly encode a slash ("/") with cl-json?

I have code that uses the cl-json library to add a line, {"main" : "build/electron.js"} to a package.json file:
(let ((package-json-pathname (merge-pathnames *app-pathname* "package.json")))
(let
((new-json (with-open-file (package-json package-json-pathname :direction :input :if-does-not-exist :error)
(let ((decoded-package (json:decode-json package-json)))
(let ((main-entry (assoc :main decoded-package)))
(if (null main-entry)
(push '(:main . "build/electron.js") decoded-package)
(setf (cdr main-entry) "build/electron.js"))
decoded-package)))))
(with-open-file (package-json package-json-pathname :direction :output :if-exists :supersede)
(json:encode-json new-json package-json))
)
)
The code works, but the result has an escaped slash:
"main":"build\/electron.js"
I'm sure this is a simple thing, but no matter which inputs I try -- "//", "/", "#//" -- I still get the escaped slash.
How do I just get a normal slash in my output?
Also, I'm not sure if there's a trivial way for me to get pretty-printed output, or if I need to write a function that does this; right now the output prints the entire package.json file to a single line.
Special characters
The JSON Spec indicates that "Any character may be escaped.", but some of them MUST be escaped: "quotation mark, reverse solidus, and the control characters". The linked section is followed by a grammar that show "solidus" (/) in the list of escaped characters. I don't think it is really important in practice (typically it needs not be escaped), but that may explain why the library escapes this character.
How to avoid escaping
cl-json relies on an internal list of escaped characters named +json-lisp-escaped-chars+, namely:
(defparameter +json-lisp-escaped-chars+
'((#\" . #\")
(#\\ . #\\)
(#\/ . #\/)
(#\b . #\Backspace)
(#\f . #\)
(#\n . #\Newline)
(#\r . #\Return)
(#\t . #\Tab)
(#\u . (4 . 16)))
"Mapping between JSON String escape sequences and Lisp chars.")
The symbol is not exported, but you can still refer to it externally with ::. You can dynamically rebind the parameter around the code that needs to use a different list of escaped characters; for example, you can do as follows:
(let ((cl-json::+json-lisp-escaped-chars+
(remove #\/ cl-json::+json-lisp-escaped-chars+ :key #'car)))
(cl-json:encode-json-plist '("x" "1/5")))
This prints:
{"x":"1/5"}

vimscript: commands that work in mappings, but not in functions

How can I rewrite these 2 commands, which work fine in a mapping, so that they will work in a function?
:if has_key(glos,#g)==1<cr>:let #j=eval('glos.'.#g)<cr>
The function concerned is executed by vim without comment, but #j remains unchanged, as if they had failed, but no message/error is generated.
Here is the complete code involved, the command that loads the dictionary, the function that does not work, and the mapping from that function that does.
" read the glossary into the dictionary, glos
let glos=eval(join(readfile("glossary.dict")))
" 2click item of interest and this will
" send image filepath to xv
" if item all-caps find same at start of its line
" If capitalized at eol find same at start of its line
" if all lower-case at eol find next occurrence of same
" look lower-case or capitalized word up in glossary.txt
" find _\d\+ (page no.) alone on its line in text
com! F call F()
function! F()
normal "ayiw"cyE"by$
let #c=substitute(#c,"[,.?':;!]\+","","g")
if #c=~'images\/ss\d\d\d*'
let #i='!display -geometry +0+0 '.#c.' &'
pkill display
#i
elseif #c==toupper(#c)
let #n=search('^'.#c,'sw')
elseif #c!=#b
let #f=3
let #g=tolower(#c)
while #f>0
try
let #j=eval('glos.'.#g)
catch
let #f=#f-1
let #g=strpart(#g,0,strlen(#g)-1)
continue
endtry
break
endwh
if #f>0
let #h=substitute(#j," glosimgs.*",'','')
if #h!=#j
let #i='!xv -geometry +0+380 '.substitute(#j,'^.\{-}\( glosimgs.*\)$','\1','').' &'
!pkill xv
#i
endif
echo #h
else
echo 'No matching entry for '.#c
endif
elseif #c=~'\u\l\+$'
let #n=search('^'.#c,'sw')
elseif #c=~'\l\+$'
norm *
elseif #c=~'^_\w\+$'
let #/='^'.#c.'$'
norm nzz
endif
endfunction
map <silent> <2-LeftMouse> "ayiw"cyE"by$:let #c=substitute(#c,"[,.?':;!]\+","","g")<cr>:if #c=~'images\/ss\d\d\d*'<cr>:let #i='!display -geometry +0+0 '.#c.' &'<cr>:pkill display<cr>:#i<cr>:elseif #c==toupper(#c)<cr>:let #n=search('^'.#c,'sw')<cr>:elseif #c!=#b<cr>:let #f=3<cr>:let #g=tolower(#c)<cr>:while #f>0<cr>:try<cr>:let #j=eval('glos["'.#g.'"]')<cr>:catch<cr>:let #f=#f-1<cr>:let #g=strpart(#g,0,strlen(#g)-1)<cr>:continue<cr>:endtry<cr>:break<cr>:endwh<cr>:if #f>0<cr>:let #h=substitute(#j," glosimgs.*",'','')<cr>:if #h!=#j<cr>:let #i='!xv -geometry +0+380 '.substitute(#j,'^.\{-}\( glosimgs.*\)$','\1','').' &'<cr>:!pkill xv<cr>:#i<cr>:endif<cr><cr<cr>>:echo #h<cr>:else<cr>:echo 'No matching entry for '.#c<cr>:endif<cr>:elseif #c=~'\u\l\+$'<cr>:let #n=search('^'.#c,'sw')<cr>:elseif #c=~'\l\+$'<cr>:norm *<cr>:elseif #c=~'^_\w\+$'<cr>:let #/='^'.#c.'$'<cr>:norm nzz<cr>:endif<cr>
Specifically, I should have written:
:if has_key(**g:**glos,#g)==1:let #j=eval('**g:**glos.'.#g)
:h g: goes straight to the heart of the matter; in a function all references are local to that function, so references to any variable outside the function must be global, by prepending 'g:' to the variable name. As I created the dictionary independent of the function, the function must reference it as a global item.
Of course, if you are not aware of 'g:', it is rather difficult to find that help reference, but that's a frequent problem using help.
And, of course, the ** surrounding g: aren't required, that's what this site gives you in lieu of bolded text, apparently.

Racket : How do i print the mysql result in a HTML page

I am trying print the values from the DB on the HTML page generated in APPLICATION.rkt
but this is what i see when i execute the code below
&createstring;&db-conn;SELECT * from students
Here is what I am trying to execute:
#lang racket
(require db)
(require web-server/servlet)
(provide/contract (start (request? . -> . response?)))
(define db-conn
(virtual-connection
(lambda () (mysql-connect #:server "localhost"
#:port 8889
#:database "SOB"
#:user "root"
#:password "root"))))
(define (start request)
(define (createstring id name sid)
(string-append "id is " id "and name is " name "and sid is " sid))
(response/xexpr
'(html
(head (title "SOB"))
(body
,#(map (h1) (map createstring (in-query db-conn "SELECT * from students"))))
)))
(require web-server/servlet-env)
(serve/servlet start
#:launch-browser? #f
#:quit? #f
#:listen-ip #f
#:port 8080
#:extra-files-paths
(list (build-path "/Users/lalith/Documents/LALITH FILES/MDX/SOB/" "htmlfiles"))
#:servlet-path
"/servlets/APPLICATION.rkt")
Any suggestions as to what I'm doing wrnog?
There are a couple problems.
First, use quasiquote (or "backquote") instead of quote; otherwise you can't escape from it with ,# (ie, unquote-splicing). In other words, change
'(html ___)
to
`(html ___)
Then, inside the ,# escape, your maps are wrong, and map doesn't work with in-query anyway. You probably want something like this instead:
,#(for/list ([(id name sid)
(in-query db-conn "SELECT id, name, sid from students")])
`(h1 ,(createstring id name sid)))
Or something like that. (The code above would make a level-1 header for each row in the table, if that's what you want.)
Edited in response to comment: It looks like id is a numeric column in the database. If you have a recent version of Racket, I recommend using ~a, which is like string-append but automatically converts non-string values to strings first. Change the definition of createstring to this:
(define (createstring id name sid)
(~a "id is " id "and name is " name "and sid is " sid))
In older versions of Racket (before ~a), use format instead (see the docs for how).

How to control indentation after an open parenthesis in Emacs

When I use emacs python-mode, if the last character of a line is an open parenthesis it indents the next line just one step in from the indentation of the previous line.
call_some_function(
some_very_long_argument_that_I_want_to_put_on_its_own_line)
I like that. Now in ecmascript-mode (which I am using for actionscript 3), it always indents to the level of the previous parenthesis.
call_some_function(
this_is_not_really_saving_me_any_horizontal_space);
How can I make ecmascript-mode indent like python-mode in this respect?
Since ecmascript-mode is based on cc-mode, you can use c-set-offset which allows you to customize any syntactic symbol's offset with the preferred value.
In your case, go to the point which is indented in the wrong level, hit C-c C-o (or type M-x c-set-offset), accept the suggested symbol (arglist-intro), and set it a new value (e.g. +, the default offset).
You can also do it programmatically in your dotemacs, for instance, with:
(add-hook 'ecmascript-mode-hook
(lambda ()
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close 0)))
ecmascript-mode seems to be based on cc-mode. If you set the indentation style for cc-mode,
it will also work for ecmascript-mode. I have the following code in my .emacs. When I use
ecmascript-mode it indents as desired:
;;{{{ c/c++ indent style variables
(require 'cc-mode)
(defconst my-c-style
'(
(c-electric-pound-behavior . 'alignleft)
(c-tab-always-indent . t)
(c-hanging-braces-alist . ((block-open)
(brace-list-open)
(substatement-open)
(defun-open before after)
(defun-close before after)
))
(c-hanging-colons-alist . ((member-init-intro before)
(inher-intro)
(case-label)
(access-label after)
(label after)
(access-key after)))
(c-cleanup-list . (scope-operator
empty-defun-braces
defun-close-semi))
(c-offsets-alist . ((arglist-close . c-lineup-arglist)
(case-label . 4)
(statement-case-intro . 4)
(access-label . -4)
(label . -)
(substatement-open . 0)
(block-open . 0)
(knr-argdecl-intro . -)))
)
"My C++/C Programming Style")
; Customizations for both c-mode and c++-mode
(defun my-c-mode-common-hook ()
; set up for my perferred indentation style, but only do it once
(c-add-style "My" my-c-style 'set-this-style)
; we like auto-newline and hungry-delete
(c-toggle-auto-hungry-state 1)
; keybindings for both C and C++. We can put these in c-mode-map
; because c++-mode-map inherits it
(define-key c-mode-map "\C-m" 'newline-and-indent)
; insert 8 tabs
(setq tab-width 8)
)
;;}}}
Thank you Török Gábor, in my case I prefered to set
(add-hook 'XXX-mode-hook
(lambda ()
(c-set-offset 'arglist-cont-nonempty '+)))
I was looking for something like this :
veryLongFunctionName (bar,
bar,
bar)
For a more exhaustive list of variables : read emacs documentation

How do I get yason:encode-alist to return the encoded string instead of sending it to a stream?

I'm trying to encode a JSON string from an alist using YASON. The problem is, the return value I'm getting is the original alist I fed it. It's printing the JSON string, and according to the documentation, it goes to *STANDARD-OUTPUT*.
Simple example session:
(ql:quickload :yason)
To load "yason":
Load 1 ASDF system:
yason
; Loading "yason"
(:YASON)
* (defparameter starving-json-eater (yason:encode-alist '(("foo" . "bar") ("baz" . "qux"))))
{"foo":"bar","baz":"qux"}
STARVING-JSON-EATER
* starving-json-eater
(("foo" . "bar") ("baz" . "qux"))
I've tried passing 'starving-json-eater into the stream parameter, but I get an error:
* (setf starving-json-eater (yason:encode-alist '(("foo" . "bar") ("baz" . "qux")) 'starving-json-eater))
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1001E06783}>:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION SB-GRAY:STREAM-WRITE-CHAR (1)>
when called with arguments
(STARVING-JSON-EATER #\{).
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [RETRY] Retry calling the generic function.
1: [ABORT] Exit debugger, returning to top level.
((:METHOD NO-APPLICABLE-METHOD (T)) #<STANDARD-GENERIC-FUNCTION SB-GRAY:STREAM-WRITE-CHAR (1)> STARVING-JSON-EATER #\{) [fast-method]
How can I get {"foo":"bar","baz":"qux"} into starving-json-eater?
You can use WITH-OUTPUT-TO-STRING to temporarily bind a variable to an open stream which writes into a string. You may even bind the special variable *standard-output* so that you only change the dynamic context of your code without providing explicitly a different stream argument (like when you redirect streams with processes).
(with-output-to-string (*standard-output*)
(yason:encode-alist '(("a" . "b"))))
Note that binding *standard-output* means that anything that writes to *standard-output* will end up being written in the string during the extent of with-output-to-string. In the above case, the scope is sufficiently limited to avoid unexpectedly capturing output from nested code. You could also use a lexical variable to control precisely who gets to write to the string:
(with-output-to-string (json)
(yason:encode-alist '(("a" . "b")) json))
The trick is to create a throwaway string output stream to catch the value, and then grab it from later:
* (ql:quickload :yason)
To load "yason":
Load 1 ASDF system:
yason
; Loading "yason"
(:YASON)
* (defparameter sated-json-eater (make-string-output-stream))
SATED-JSON-EATER
* (yason:encode-alist '(("foo" . "bar") ("baz" . "qux")) sated-json-eater)
(("foo" . "bar") ("baz" . "qux"))
* (defparameter json-string (get-output-stream-string sated-json-eater))
JSON-STRING
* json-string
"{\"foo\":\"bar\",\"baz\":\"qux\"}"
This can be hidden away in a function:
(defun json-string-encode-alist (alist-to-encode)
(let ((stream (make-string-output-stream)))
(yason:encode-alist alist-to-encode stream)
(get-output-stream-string stream)))