G'day gurus,
I've written some code that leverages a Java library that makes uses of the visitor pattern. What I'd like is to hide all the messy details of the visitor etc. behind a single Clojure function that takes the input parameter(s) and returns a simple data structure containing all of the state derived by the visitor.
The trick is that there are multiple "visitXXX" callbacks on the Java side and there's no easy way to return state back out of them (Java, being Java, assumes any state that gets built up by the various visitors is stored in instance variables).
What I've done (and which seems to work great, fwiw) is define an atom in a let block, and have each of my visitor functions swap! the atom with an updated value when they're called by the Java visitation code. I then return the deref'ed atom out the end of the main "driver" function, after the Java visitor completes.
My question is: is this an appropriate usage of an atom? If not, is there a more idiomatic way to do this?
If anyone's interested, the code in question is here.
Disclaimer: I'm still a Clojure n00b so that code is probably hideous to the more discerning eye. Comments / feedback / critiques welcome!
Thanks in advance!
Your approach using an atom is fine and looks good and clojurish.
If you are looking for other approaches as well; since you can split your problem into some code that will produce and answer (your visitor) and some other code that will need the answer when it is available, Clojure's promise and deliver functions may be well suited.
If you create the promises in the let block, then have the visitor deliver the results to the promise.
Related
I need to do a big trick and am keen on hearing your suggestions.
What I need is a macro that takes ordinary clojure code peppered with a special "await" form. The await forms contains only clojure code and are supposed to return the code's return value. Now, what I want is that when I run whatever is being produced by this macro, it should stop executing when the first "await" form is due for evaluation.
Then, it should dump all the variables defined in its scope so far to the database (I will ignore the problem that not all Clojure types can be serialised to EDN, e.g. functions can't), together with some marker of the place it has stopped in.
Then, if I want to run this code again (possibly on a different machine, another day) - it will read its state from the DB and continue where it stopped.
Therefore I could have, for example:
(defexecutor my-executor
(let [x 7
y (await (+ 3 x))]
(if (await (> y x))
"yes"
"no")))
Now, when I do:
(my-executor db-conn "unique-job-id")
the first time I should get a special return value, something like
:deferred
The second time it should be like this as well, only the third time a real return value should be returned.
The question I have is not how to write such executor, but rather how to gather information from within the macro about all the declared variables to be able to store them. Later I also want to re-establish them when I continue execution. The await forms can be nested, of course :)
I had a peek into core.async source code because it is doing a similar thing inside, but what I have found there made me shiver - it seems they employ the Clojure AST analyser to get this info. Is this really so complex? I know of &env variable inside a macro, but do not have any idea how to use it in this situation. Any help would be appreciated.
And one more thing. Please do not ask me why I need this or that there is a different way of solving a problem - I want this specific solution.
I will ignore the problem that not all Clojure types can be serialised to EDN, e.g. functions can't
If you ignore this, it will be very restrictive for the kinds of Clojure expressions you can handle. Functions are everywhere, e.g. in the implementation of things like doseq and for. Likewise, a lot of interesting programs will depend on some Java object like a file handle or whatever.
The question I have is not how to write such executor, but rather how to gather information from within the macro about all the declared variables to be able to store them.
If you manage to write such an executor, I suspect its implementation will need to know about local variables anyway. So you can put off this question until you are done implementing your executor - you will probably find it obsolete, if you can implement your executor.
I had a peek into core.async source code because it is doing a similar thing inside, but what I have found there made me shiver - it seems they employ the Clojure AST analyser to get this info. Is this really so complex?
Yes, this is very intrusive. You are basically writing a compiler. Thank your lucky stars they wrote the analyzer for you already, instead of having to analyze expressions yourself.
I know of &env variable inside a macro, but do not have any idea how to use it in this situation.
This is the easy part. If you like, you can write a simple macro that gives you all the locals in scope. This question has been asked and answered before, e.g. in Clojure get local lets.
And one more thing. Please do not ask me why I need this or that there is a different way of solving a problem - I want this specific solution.
This is generally an unproductive attitude when asking a question. It's admitting you're posing an XY problem, and still refusing to tell anyone what the Y is.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Backstory: I've made a lot of large and relatively complex projects in Java, have a lot of experience in embedded C programming. I've got acquainted with scheme and CL syntax and wrote some simple programms with racket.
Question: I've planned a rather big project and want to do it in racket. I've heard a lot of "if you "get" lisp, you will become a better programmer", etc. But every time I try to plan or write a program I still "decompose" the task with familiar stateful objects with interfaces.
Are there "design patterns" for lisp? How to "get" lisp-family "mojo"? How to escape object-oriented constraint on your thinking? How to apply functional programming ideas boosted by powerful macro-facitilties? I tried studying source code of big projects on github (Light Table, for instance) and got more confused, rather than enlightened.
EDIT1 (less ambigious questions): is there a good literatue on the topic, that you can recommend or are there good open source projects written in cl/scheme/clojure that are of high quality and can serve as a good example?
A number of "paradigms" have come into fashion over the years:
structured programming, object oriented, functional, etc. More will come.
Even after a paradigm falls out of fashion, it can still be good at solving the particular problems that first made it popular.
So for example using OOP for a GUI is still natural. (Most GUI frameworks have a bunch of states modified by messages/events.)
Racket is multi-paradigm. It has a class system. I rarely use it,
but it's available when an OO approach makes sense for the problem.
Common Lisp has multimethods and CLOS. Clojure has multimethods and Java class interop.
And anyway, basic stateful OOP ~= mutating a variable in a closure:
#lang racket
;; My First Little Object
(define obj
(let ([val #f])
(match-lambda*
[(list) val]
[(list 'double) (set! val (* 2 val))]
[(list v) (set! val v)])))
obj ;#<procedure:obj>
(obj) ;#f
(obj 42)
(obj) ;42
(obj 'double)
(obj) ;84
Is this a great object system? No. But it helps you see that the essence of OOP is encapsulating state with functions that modify it. And you can do this in Lisp, easily.
What I'm getting at: I don't think using Lisp is about being "anti-OOP" or "pro-functional". Instead, it's a great way to play with (and use in production) the basic building blocks of programming. You can explore different paradigms. You can experiment with ideas like "code is data and vice versa".
I don't see Lisp as some sort of spiritual experience. At most, it's like Zen, and satori is the realization that all of these paradigms are just different sides of the same coin. They're all wonderful, and they all suck. The paradigm pointing at the solution, is not the solution. Blah blah blah. :)
My practical advice is, it sounds like you want to round out your experience with functional programming. If you must do this the first time on a big project, that's challenging. But in that case, try to break your program into pieces that "maintain state" vs. "calculate things". The latter are where you can try to focus on "being more functional". Look for opportunities to write pure functions. Chain them together. Learn how to use higher-order functions. And finally, connect them to the rest of your application -- which can continue to be stateful and OOP and imperative. That's OK, for now, and maybe forever.
A way to compare programming in OO vs Lisp (and "functional" programming in general) is to look at what each "paradigm" enables for the programmer.
One viewpoint in this line of reasoning, which looks at representations of data, is that the OO style makes it easier to extend data representations, but makes it more difficult to add operations on data. In contrast, the functional style makes it easier to add operations but harder to add new data representations.
Concretely, if there is a Printer interface, with OO, it's very easy to add a new HPPrinter class that implements the interface, but if you want to add a new method to an existing interface, you must edit every existing class that implements the interface, which is more difficult and may be impossible if the class definitions are hidden in a library.
In contrast, with the functional style, functions (instead of classes) are the unit of code, so one can easily add a new operation (just write a function). However, each function is responsible for dispatching according to the kind of input, so adding a new data representation requires editing all existing functions that operate on that kind of data.
Determining which style is more appropriate for your domain depends on whether you are more likely to add representations or operations.
This is a high-level generalization of course, and each style has developed solutions to cope with the tradeoffs mentioned (eg mixins for OO), but I think it still holds to a large degree.
Here is a well-known academic paper that captured the idea 25 years ago.
Here are some notes from a recent course (I taught) describing the same philosophy.
(Note that the course follows the How to Design Programs curriculum, which initially emphasizes the functional approach, but later transitions to the OO style.)
edit: Of course this only answers part of your question and does not address the (more or less orthogonal) topic of macros. For that I refer to Greg Hendershott's excellent tutorial.
A personal view:
If you parameterise an object design in the names of the classes and their methods - as you might do with C++ templates - then you end up with something that looks quite like a functional design. In other words, functional programming does not make useless distinctions between similar structures because their parts go by different names.
My exposure has been to Clojure, which tries to steal the good bit from object programming
working to interfaces
while discarding the dodgy and useless bits
concrete inheritance
traditional data hiding.
Opinions vary about how successful this programme has been.
Since Clojure is expressed in Java (or some equivalent), not only can objects do what functions can do, there is a regular mapping from one to the other.
So where can any functional advantage lie? I'd say expressiveness. There are lots of repetitive things you do in programs that are not worth capturing in Java - who used lambdas before Java provided compact syntax for them? Yet the mechanism was always there.
And Lisps have macros, which have the effect of making all structures first class. And there's a synergy between these aspects that you will enjoy.
The "Gang of 4" design patterns apply to the Lisp family just as much as they do to other languages. I use CL, so this is more of a CL perspective/commentary.
Here's the difference: Think in terms of methods that operate on families of types. That's what defgeneric and defmethod are all about. You should use defstruct and defclass as containers for your data, keeping in mind that all you really get are accessors to the data. defmethod is basically your usual class method (more or less) from the perspective of an operator on a group of classes or types (multiple inheritance.)
You'll find that you'll use defun and define a lot. That's normal. When you do see commonality in parameter lists and associated types, then you'll optimize using defgeneric/defmethod. (Look for CL quadtree code on github, for an example.)
Macros: Useful when you need to glue code around a set of forms. Like when you need to ensure that resources are reclaimed (closing files) or the C++ "protocol" style using protected virtual methods to ensure specific pre- and post-processing.
And, finally, don't hesitate to return a lambda to encapsulate internal machinery. That's probably the best way to implement an iterator ("let over lambda" style.)
Hope this gets you started.
I've been working into a small game just for learning.
The intent of the game is that it is going to be online, but I have some trouble on how to serialize the commands sent from server to client.
There is a lot of different commands that can be sent, and handling this manually is driving me insane. At the moment I'm using lots of 'ifs' to do this, but I hope there is a Design Pattern that helps.
I would like to unpack the message in different kinds of objects so I could get them from some kind of queue and treat them efficiently... But I would like to do it partially or completely automatic.
Is there a good practice to solve this kind of problem? It would be good if it was efficient too.
Thanks in advance.
PS: Although this is a conceptual question, I'm using C++, so some specific solution would be fine too.
Try a Factory pattern. Something along these lines is a useful factory model.
Make a base class that provides methods for serialising and deserialising data from a stream, and register your derived types by name or some other identifier with the factory.
You can package up a command in a bundle with a header that tells the receiver what type to create. When you read a command, you ask the factory to create the correct type. Then returned type can then be called to deserialise its data.
Here, I'm assuming that some commands have extra data.
Once you have popped the command out of the queue for processing, you can call its 'Execute' method.
There is a design pattern called "actors", which might be what you want. Features:
natual and simplified concurrency model.
could be used together with pattern matching over messages (eliminate "ifs").
Language 'scala' provides good support for this design pattern and perfectly meet your need. However, I don't know whether there is similar solution in C++.
I've been trying to find anything that discusses when you should favor the use of monads over actors (in concurrency scenarios), but I've found nothing. In particular, I'm wondering about the use of the Reactive Extensions (LINQ to Events) vs. F#'s MailboxProcessor. Please give examples in addition to any philosophical reasoning you might have.
Update
For better context, the Reactive Extensions implement the continuation monad in the form of IObservable/IObserver. I'm not necessarily saying I have to use F#, just that F# has a concrete "actor model" available in a .NET language in the form of MailboxProcessor<'T>.
What I'm trying to understand is when to use a monad (in this case a continuation monad) vs. an actor model for concurrency purposes. Where the monad (as I understand it) doesn't introduce state, the actor has its own internal state that is modified as necessary to provide protected access.
I've seen a number of examples of using both: Rx and node.js (CPS, not really the continuation monad) vs. F#'s MailboxProcessor and Scala's Akka framework. I just don't know why you would choose one over the other.
I'm not sure that the question makes sense as phrased - there are many different monads (e.g. the identity monad, the list monad, the option monad, ...), most of which have nothing to do with concurrency. Furthermore, it would be helpful to know more about the particular scenario that you're dealing with - "concurrency" is a bit of a nebulous topic. Depending on what you're trying to achieve, F#'s async workflows (which are built on the Async monad) might be your best bet.
If you're using F#, I'd recommend against using LINQ-to-anything directly, since those libraries have a very alien feel when accessed via F#. You could, however, create pleasant F# wrappers (such as the existing Seq and Observable modules). Additionally, for monadic types, you could create a computation expression builder (e.g. you could create a builder using the Reactive Extensions which would enable you to use computation expressions to build and compose IObservables).
Please excuse my newbie-ness as I'm just learning F#.
I'm intrigued to see the use of RX in place of a MailboxProcessor, if you have any links to relevant materials.
With my limited understanding; I would choose MbP's in my own code as events are a bit messy to set up in F# (from what I can take from this article: MSDN). And you need events for RX to hook into right?
Where as with a MbP all I need is a discriminated union of messages, a list of functions I wish to be executed when a given message is received. And the mail box processor that handles this.
This all looks pretty neat in the code. I can bunch my MbP's together in a module then my "object" module looks like
Record
Message DU
Wrapper with some getters and setters that post data to the MbP
For me this looks a lot neater than it would If I wrote my code with events as described in that MSDN article I linked to.
Though I am just an F# junior so I may be a miles off with my reckoning and it is a look-&-feel thing rather than a suitability-for-purpose choice (as I'm not qualified to make that call, yet)
Would you accept answers from the Scala world?
If you seek "a purely functional alternative to actor model" then please see this great post from Paul Chiusano's blog
pchiusano.blogspot.ro/2010/01/actors-are-not-good-concurrency-model.html
(archived here: http://archive.is/NxNLc)
and some references below:
http://noelwelsh.com/programming/2013/03/04/why-i-dont-like-akka-actors/
Actors do not Compose
Akka’s Actors are not Usefully Typed
The type system is the reason we use Scala.
https://opencredo.com/akka-typed/
Unfortunately, the current API suffers from a few drawbacks, which are to a good degree associated with the lack of type safety
http://doc.akka.io/docs/akka/snapshot/scala/typed.html
Status of this Project and Relation to Akka Actors
Akka Typed is the result of many years of research and previous attempts (including Typed Channels in the 2.2.x series) and it is on its way to stabilization, but maturing such a profound change to the core concept of Akka will take a long time
A side-effect of this is that behaviors can now be tested in isolation without having to be packaged into an Actor, tests can run fully synchronously without having to worry about timeouts and spurious failures. Another side-effect is that behaviors can nicely be composed and decorated
Composable application architecture with reasonably priced monads
https://youtu.be/M258zVn4m2M?t=1955
https://youtu.be/M258zVn4m2M?t=1986
The concept of "function passing style" from Heather Miller might be key to a distributed functional programming model.
SF Scala: Heather Miller, Function-Passing Style, A New Model for Distributed Programming
Update 12/2018 : now we can use Aecor which provide the means to:
implement business domain logic with a functional programming model and
use an Akka based runtime
"behaviors belong to the domain layer and runtime is out there in the infrastructure layer."
Source: https://pavkin.ru/aecor-part-3/, http://aecor.io
I'm going to respond to my own question and say you should use both. This is based on Don Syme's post. A MbP uses the Async computation to do its work, and the Async is a thread-aware continuation monad. Looks like you can use it by itself for some uses, but the MbP definitely requires it.
I don't really like this answer, and I'd be happy for someone to respond with a better explanation of when to use each.
Updated:
See MiniRx, which is now apart of FSharpx, for an implementation of an Rx-style monad implemented using MailboxProcessor. As MailboxProcessor is itself implemented using the async monad, these pieced to indeed work together. They are just different means of abstraction.
I've written a handful of basic 2D shooter games, and they work great, as far as they go. To build upon my programming knowledge, I've decided that I would like to extend my game using a simple scripting language to control some objects. The purpose is more about the general process of design of writing a script parser / executer than the actual control of random objects.
So, my current line of thought is to make use of a container of lambda expressions (probably a map). As the parser reads each line, it will determine the type of expression. Then, once it has decided the type of instruction and discovered whatever values it has to work with, it will then open the map to the kind of expression and pass it any values it needs to work.
A more-or-less pseudo code example would be like this:
//We have determined somehow or another that this is an assignment operator
someContainerOfFunctions["assignment"](whatever_variable_we_want);
So, what do you guys think of a design like this?
Not to discourage you, but I think you would get more out of embedding something like Squirrel or Lua into your project and learning to use the API and the language itself. The upside of this is that you'll have good performance without having to think about the implementation.
Implementing scripting languages (even basic ones) from scratch is quite a task, especially when you haven't done one before.
To be honest: I don't think it's a good idea as you described, but does have potential.
This limits you with an 'annoying' burden of C++'s static number of arguments, which is may or may not what you want in your language.
Imagine this - you want to represent a function:
VM::allFunctions["functionName"](variable1);
But that function takes two arguments! How do we define a dynamic-args function? With "..." - that means stdargs.h and va_list. unfortunately, va_list has disadvantages - you have to supply an extra variable that will somehow be of an information to you of how many variables are there, so we change our fictional function call to:
VM::allFunctions["functionName"](1, variable1);
VM::allFunctions["functionWithtwoArgs"](2, variable1, variable2);
That brings you to a new problem - During runtime, there is no way to pass multiple arguments! so we will have to combine those arguments into something that can be defined and used during runtime, let's define it (hypothetically) as
typedef std::vector<Variable* > VariableList;
And our call is now:
VM::allFunctions["functionName"](varList);
VM::allFunctions["functionWithtwoArgs"](varList);
Now we get into 'scopes' - You cannot 'execute' a function without a scope - especially in embedded scripting languages where you can have several virtual machines (sandboxing, etc...), so we'll have to have a Scope type, and that changes the hypothetical call to:
currentVM->allFunctions["functionName_twoArgs"].call(varList, currentVM->currentScope);
I could continue on and on, but I think you get the point of my answer - C++ doesn't like dynamic languages, and it would most likely not change to fit it, as it will most likely change the ABI as well.
Hopefully this will take you to the right direction.
You might find value in Greg Rosenblatt's series of articles of at GameDev.net on creating a scripting engine in C++ ( http://www.gamedev.net/reference/articles/article1633.asp ).
The approach he takes seems to err on the side of minimalism and thus may be either a close fit or a good source of implementation ideas.