...
> I just want to practice Spanish! (Actually, I'd rather program
> Clojure, but I don't like wasting my time trying to do elementary
> things that SHOULD ... JUST ... WORK.) Can anybody suggest anything
> that will enable me to write this simple program that any middle-
> school student would find, well, basic if written in BASIC? Thanks.
The whole JVM ecosystem seems built around client-server
communications, noninteractive jobs, and client-side GUI; not
client-side console interaction. It's easier to do something like this
using a Swing GUI with a read-only JTextArea holding the interaction
history above a one-line JTextField used to submit new input; stick an
ActionListener on the JTextField and it will get called when enter is
pressed in the field. Or you can use something like this to sugar it
up:
(defmacro text-line [input-var & body]
`(let [f# (javax.swing.JTextField.)]
(doto f
(setEditable true)
(setColumns 60)
(.addActionListener
(proxy [ActionListener] []
(actionPerformed [_]
(let ~(conj input-var `(.getText f#))
(.setText f# "")
~@body)))))))
Sample usage:
(let [field (text-line [line] (println line))]
...
(.add some-panel field java.awt.layout.BorderLayout/SOUTH))
Untested.
"This is currently impossible due to a bug in ant; it just swallows
stdin completely, and they seem to have no intention of fixing it."
// raek
> ... *How* does the
> word "easier" belong in that sentence, when I all I want to do is read
> input from the keyboard?!
>
> My modest proposal:
> ...
I'm writing to support the sentiment that Gregg expressed here with regard to this issue, and also his broader proposal.
List members offered several clever and helpful workarounds in response to Gregg's post, along with pointers to the reasons for the current situation. Great!
But still, I will humbly submit that it's totally freakin' nutso that it should be so hard to do basic user interaction.
FWIW I looked back at materials I used to teach clojure last semester and saw that I presented some stuff based on read-line in the REPL and it must have worked in the environment that I was using at the time, which was Eclipse/CCW on a mac. But now I do remember that some students who were using this for simple text adventure games had problems, although I don't remember the details. They may have been using other platforms. In any event I will include the code that I shared with the students at that time below... yes, I know that some of you will think that I shouldn't have used eval, etc., but for the purpose I think it was fine.... and my view that stuff like this should work without clever workarounds in any Clojure environment that isn't labeled as broken.
-Lee
(ns commandline)
(defn read-and-do-line
"Get from the user and execute a command line without parentheses,
where the first thing on the line is the name of a function and the
rest of the line is arguments (which will not be evaluated)."
[]
(print "command: ")
(flush)
(let [line (read-line)
list-of-things (read-string (str "(" line ")"))]
(apply (eval (first list-of-things)) (rest list-of-things))))
(defn inc-and-print [number] (println (inc number))) ;; just an example command to call
(defn list-and-print [& args] (println (apply list args))) ;; another
(def in-loop (atom false)) ;; just to control the command loop below
(defn quit [] (reset! in-loop false)) ;; a function to get out of the loop
(defn command-loop []
(reset! in-loop true)
(loop []
(when @in-loop
(read-and-do-line)
(recur))))
;; 1:3 commandline=> (command-loop)
;; command: inc-and-print 3
;; 4
;; command: list-and-print :a :b :c 1 2 3
;; (:a :b :c 1 2 3)
;; command: quit
;; nil
;; 1:7 commandline=>
I'm curious as to what percentage of developers are writing
console-based applications (in any language)?
What do the processes look like in other languages? How are those
processes different to what happens with Clojure?
With the following test program, t.clj...
(println "Testing...")
(let [a (read-line)]
(println "> " a))
...I can open up a REPL, do (load-file "t.clj") and it runs as
expected. I can also type clj run t.clj and it works just fine (can't
remember where I got that script from - it just wraps the java command
to start Clojure).
Now, I will concede that lein run t.clj does not work - and that does
seem a bit odd given that lein repl then (load-file "t.clj") works but
if it's a technical limitation with the run task, fair enough.
However, given the clj run command, I can add a #! line to my Clojure
scripts, make them execute and just run them:
#!/usr/bin/env clj run
(println "Testing...")
(let [a (read-line)]
(println "> " a))
Now I can just type ./t.clj and it works as expected...
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/
"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)
> On Sat, Apr 9, 2011 at 6:46 AM, Lee Spector <lspe...@hampshire.edu> wrote:
>> But still, I will humbly submit that it's totally freakin' nutso that it should be so hard to do basic user interaction.
>
> I'm curious as to what percentage of developers are writing
> console-based applications (in any language)?
>
I don't know -- probably quite low -- but I would predict that the percentage of students learning Lisp-like languages who would be writing console-based interactive programs is quite high. Lots of curricula are based on this sort of thing, and even people who aren't students may do some of this first since it seems like it shouldn't rely on understanding libraries or the java ecosystem or whatever. So funky behavior related to simple text I/O may be confusing people who are least likely to know how to work around it.
> What do the processes look like in other languages? How are those
> processes different to what happens with Clojure?
Code for doing this sort of thing in Common Lisp or Scheme looks almost identical to the simple Clojure code we've seen on this thread, with the most significant difference being that the Clojure version apparently doesn't work if you launch your REPL and run your code in some of the commonly recommended ways. (Note: I haven't tried all of the ways that have been discussed, but the consensus seems to be that it does indeed fail.)
-Lee
I wouldn't expect it to be "quite low", but I build them regularly,
and so do most of the people I work with. On unix systems, the
predominate way to plug to programs together is still via the standard
IO pipes, which the programs - even if normally invoked from some
visual tool - can be used from the command line. And many of us work
develop on one system, then deploy on something else via SSH, so being
able to deal with things on the command line - even if it also
provides some kind of GUI - is a useful feature.
Admittedly, JVM languages don't lend themselves to such things, what
with having to either start it on every command or have some kind of
server running to avoid that.
> Code for doing this sort of thing in Common Lisp or Scheme looks
> almost identical to the simple Clojure code we've seen on this
> thread, with the most significant difference being that the Clojure
> version apparently doesn't work if you launch your REPL and run your
> code in some of the commonly recommended ways.
This sounds more like an issue with those "commonly recommended ways"
than with clojure or it's REPL, since it works fine running from a
shell.
<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/consulting.html
Independent Software developer/SCM consultant, email for more information.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
it surprised me that you used an atom to run the event loop. A simple
loop/recur also works, at least in clojure 1.2.1:
(loop []
(let [input (read-line)]
(when (pos? (count input))
(println (pick phrases))
(recur))))
Just for the record.
Best,
Albert