On Fri, May 21, 2010 at 11:42:13AM -0700, Niels Mayer wrote:
On Fri, May 21, 2010 at 8:33 AM, torbenh
<torbenh(a)gmx.de> wrote:
and i really find bigger programs pretty confusing in dynamic languages
where variables arent annotated with types.
That's just because the programmer wasn't fastidious enough in naming
variables or structuring the program. You can program badly in any language.
Often dynamic language "programs" often started as a simple script that
grew... Every program needs refactoring eventually.
i think that code is pretty hard to read.
and concision isnt always good.
To each his own...
sure. i have never liked lisp like languages.
but my main feeling about them, is that you need to write too much.
which seems to be the contrary of how you are arguing.
there is a reason why people call perl a
"write-only" language.
Did I even mention perl? Blech. I was suggesting Clojure and Groovy, for
their readability/elegance/simplicity/ease-of-use and ability to reuse all
of Java classes, JVM advances, portability, wide-adoption, security, etc.
no you didnt mention perl. but perl is often hailed for being so
concise.
Church's work was the inspiration for the development of Lisp as a language.
The "able to parallelize any valid faust code" is a fundamental corollary to
functional programming and forms the basis of numerous implementations:
http://en.wikipedia.org/wiki/Concurrent_computing (somebody should add Faust
as it's not there, clojure and scala are, and are also much more widely
known).
Clojure, is the next step past that, as it directly integrates language
structures enabling parallelism, along with the functional style needed to
make it all work:
http://clojure.org/agents
overall when it comes to RT stuff.... either you
use a language which
gives you control over heap allocation. or the language must be
specifically designed for RT operation.
so we end up with c/c++ again.
or faust.
And for the things that people do in C or Faust, that's exactly what they
should continue doing.
However, it is simply bad architecture to muddle up RT code with arbitrary
UI code. It's much better to setup a simple network protocol so that the RT
code only need listen on a socket for any I/O related to changing it's
state. Which sounds like exactly the path taken with OSC control of plugins,
etc:
http://dssi.sourceforge.net/why-use.html "DSSI separates the plugin and user
interface, using standard Open Sound Control (OSC) messages to communicate
between them. This ensures that the plugin's controls are consistently
externally available, provides a guarantee of automatability, and encourages
clean plugin structure."
And then just write an external UI program that talks OSC and attempts to
keep up as best possible with the realtime processing going on in a
different process. Allowing that realtime process to determine scheduling
and receipt of UI events.
Why muddle-up perfectly good realtime code w/ a bunch of GUI?
the reason why dssi does this is not that things would muddle up.
its a workaround for the "Qt and gtk+ dont really work in a single
process" problem.
i dont see why "implementing 2 things in the same language" muddles
anything up. i admit that it does enforce not muddling it up.
but basically you end up with 2 layers of marshalling.
one layer for the marshalling from normal thread to the RT thread.
and another for the osc marshalling.
i consider cpu time pretty precious in RT contexts.
GUIs get pretty sluggish, once the DSP load hits 50%
and this kind of marshalling/copying data around doesnt help at all.
all this stuff
you posted is nice... but i dont really have any hopes,
that this stuff would become useable in the next 2 years.
2 years is like 10 in internet time.
stop dreaming :)
But that's what I do!
Looks like I won't have to dream long:
http://github.com/rosejn/midi-clj
http://github.com/rosejn/osc-clj
http://bitbucket.org/amb/clojure-snippets/src/tip/audio.clj
http://github.com/amb/rezo
http://osdir.com/ml/clojure/2010-01/msg00900.html
(defn osc-recv
"Receive a single message on an osc path (node) with an optional
timeout."
[peer path & [timeout]]
(let [p (promise)]
(osc-handle peer path (fn [msg]
(deliver p msg)
(osc-remove-handler)))
(let [res (try
(if timeout
(.get (future @p) timeout TimeUnit/MILLISECONDS)
@p)
(catch TimeoutException t
nil))]
res)))
I bet the above would combine quite nicely with a
http://qtjambi.sourceforge.net/ GUI via Clojure....
hmm... its probably a matter of taste.
but i find the equivalen c++ easier to read.
assuming we have a proper modern c++ osc lib:
boost::unique_future<OscMsg>
osc_recv (OscPeer peer, std::string path)
{
boost::shared_ptr< boost::promise<OscMsg> > spromise( new
boost::promise<OscMsg> )
peer.add_handler( path, [=]( OscMsg msg )
{
spromise->set_value( msg );
peer->remove_handler( path );
} );
return spromise->get_future();
}
main()
{
auto msg = osc_recv( peer, "bla" );
try {
msg.timed_wait( 1000 );
cout << msg.get();
} catch {
cout << "didnt work";
}
}
--
torben Hohn