[ANN] A couple of libraries for functional reactive web programming - Ulmus & Recurrent

2018-03-30 Thread Jeremy Kross
Hey everybody,

I've been hacking on these for about two years, but I only recently got 
around to documenting them to a place where they're semi-presentable.

First up in Ulmus, a library for doing frp style programming in 
Clojurescript.  I apes the Elm API to some degree.  Really just 
higher-level core.async, but I've found it pretty great to work with. 

https://github.com/jeremykross/ulmus

Second is Recurrent, a library for building functionally reactive web 
components.  It's inspired most directly by cycle.js but I think there's 
good bit of novelty there as well.  Can't say that it's for everybody, but 
the way my mind works, it's been real joy to develop and use.

https://github.com/jeremykross/recurrent

Hope somebody else will find these cool as well.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] com.walmartlabs/schematic 1.1.0

2018-03-30 Thread Howard Lewis Ship
... and some notes on how we got there:
https://medium.com/@hlship/schematic-92b0b6ffdb26

On Fri, Mar 30, 2018 at 12:30 PM, Steve Ashton 
wrote:

> Schematic is a Clojure library which aids in assembling Component systems
> from configuration data.
>
> * Expects components to implement the Component/Lifecycle protocol
> * Prefers pure data for declaring dependencies
> * Provides a simple mechanism for assembling/starting just a subset of
> Components
> * Avoids the pattern of passing a large bag of config data through down
> through levels of Component creation functions
>
> https://github.com/walmartlabs/schematic
>
> This is the first public release of this library, but we've been using it
> in production systems at WalmartLabs for more than a year.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Howard M. Lewis Ship

Senior Mobile Developer at Walmart Labs

Creator of Apache Tapestry

(971) 678-5210
http://howardlewisship.com
@hlship

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[ANN] com.walmartlabs/schematic 1.1.0

2018-03-30 Thread Steve Ashton
Schematic is a Clojure library which aids in assembling Component systems 
from configuration data. 

* Expects components to implement the Component/Lifecycle protocol
* Prefers pure data for declaring dependencies 
* Provides a simple mechanism for assembling/starting just a subset of 
Components
* Avoids the pattern of passing a large bag of config data through down 
through levels of Component creation functions

https://github.com/walmartlabs/schematic

This is the first public release of this library, but we've been using it 
in production systems at WalmartLabs for more than a year.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Writing a text adventure in Clojure

2018-03-30 Thread Karsten Schmidt
Hi Will,

have a look at this workshop repository, in which we developed a
simple text adventure framework:
https://github.com/learn-postspectacular/resonate-workshop-2014

Hth! K.

On 30 March 2018 at 16:01, Gary Johnson  wrote:
> Hi Will,
>
> Welcome to the wide world of functional programming, where data flows, and
> functions transmute without destroying their inputs.
>
> As some others in this thread have already suggested, a general approach to
> viewing any problem space from a functional perspective is to imagine your
> problem as a pipeline of data transformations from start to finish. To the
> greatest extent possible, try to represent your data transformations as pure
> functions over immutable arguments rather than holding any global state in a
> var and mutating it at each time step.
>
> In the context of a game program, consider depicting all of your game state
> as a single hierarchical map. Then thread this map through each function and
> return a new derived map as each output result.
>
> ```clojure
> (def world-state {:flags #{}
> :location :fancy-room
> :inventory #{:sledgehammer :car-keys :lamp}
> :rooms {:creepy-corridor {:name "Creepy Corridor"
> :description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw
> :troll-doll}}
> :fancy-room {:name "Fancy Room"
> :description "The fanciest!" :items #{:chandelier :toy-poodle
> :looking-glass}}
> ...}})
>
> ```
> Let's imagine this is the initial world state. When your application starts
> up, it enters into the game loop (which would be a nice, friendly recursion,
> of course). In each round of the game loop, you call a sequence of functions
> to get the description of the current room, print it out, ask the user for
> the next command, process that command, and then recurse back to the top of
> the next iteration of the game loop. Although printing to stdout and reading
> from stdin are obviously side effecting functions, you should be able to
> keep your functions for retrieving the room description and processing the
> user's command as pure functions of the current world-state. Just make sure
> that the functions that process a user's command always return a new copy of
> the world-state value. When you want to save the game, just write out the
> world-state to an EDN file. By reading it back in again later, you can
> restore the game to exactly the same state it was in before.
>
> In response to your specific question about having a different room
> description after some event has happened, consider this approach:
>
> ```clojure
> (defn do-important-plot-changing-action [world-state]
> (-> world-state
>  (update :flags conj :major-plot-point-reached)
>  (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't
> nearly as fancy anymore!")))
> ```
>
> That is, the function just uses assoc, assoc-in, update, and update-in to
> modify the values in the new map and return it for use in future iterations
> of the game loop. And that's pretty much all there is to it. You just pass
> the changing world state down through the stack rather than mutating it in
> place on the heap. (Ultimately, the world-state data structure is, of
> course, actually stored on the heap, and you are just passing references to
> it through the stack, but I hope you get my meaning here.)
>
> Good luck and happy hacking!
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



-- 
Karsten Schmidt
http://postspectacular.com | http://thi.ng | http://toxiclibs.org

On 30 March 2018 at 16:01, Gary Johnson  wrote:
> Hi Will,
>
> Welcome to the wide world of functional programming, where data flows, and
> functions transmute without destroying their inputs.
>
> As some others in this thread have already suggested, a general approach to
> viewing any problem space from a functional perspective is to imagine your
> problem as a pipeline of data transformations from start to finish. To the
> greatest extent possible, try to represent your data transformations as pure
> functions over immutable arguments rather than holding any global state in a
> var and mutating it at each time step.
>
> In the 

Re: Writing a text adventure in Clojure

2018-03-30 Thread Gary Johnson
Hi Will,

Welcome to the wide world of functional programming, where data flows, and 
functions transmute without destroying their inputs.

As some others in this thread have already suggested, a general approach to 
viewing any problem space from a functional perspective is to imagine your 
problem as a pipeline of data transformations from start to finish. To the 
greatest extent possible, try to represent your data transformations as 
pure functions over immutable arguments rather than holding any global 
state in a var and mutating it at each time step.

In the context of a game program, consider depicting all of your game state 
as a single hierarchical map. Then thread this map through each function 
and return a new derived map as each output result.

```clojure
(def world-state {:flags #{}
:location :fancy-room
:inventory #{:sledgehammer :car-keys :lamp}
:rooms {:creepy-corridor {:name "Creepy Corridor" 
:description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw 
:troll-doll}}
:fancy-room {:name "Fancy Room" 
:description "The fanciest!" :items #{:chandelier :toy-poodle 
:looking-glass}}
...}})

```
Let's imagine this is the initial world state. When your application starts 
up, it enters into the game loop (which would be a nice, friendly 
recursion, of course). In each round of the game loop, you call a sequence 
of functions to get the description of the current room, print it out, ask 
the user for the next command, process that command, and then recurse back 
to the top of the next iteration of the game loop. Although printing to 
stdout and reading from stdin are obviously side effecting functions, you 
should be able to keep your functions for retrieving the room description 
and processing the user's command as pure functions of the current 
world-state. Just make sure that the functions that process a user's 
command always return a new copy of the world-state value. When you want to 
save the game, just write out the world-state to an EDN file. By reading it 
back in again later, you can restore the game to exactly the same state it 
was in before.

In response to your specific question about having a different room 
description after some event has happened, consider this approach:

```clojure
(defn do-important-plot-changing-action [world-state]
(-> world-state
 (update :flags conj :major-plot-point-reached)
 (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't 
nearly as fancy anymore!")))
```

That is, the function just uses assoc, assoc-in, update, and update-in to 
modify the values in the new map and return it for use in future iterations 
of the game loop. And that's pretty much all there is to it. You just pass 
the changing world state down through the stack rather than mutating it in 
place on the heap. (Ultimately, the world-state data structure is, of 
course, actually stored on the heap, and you are just passing references to 
it through the stack, but I hope you get my meaning here.)

Good luck and happy hacking!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Writing a text adventure in Clojure

2018-03-30 Thread Tim Visher
http://landoflisp.com/ is specifically about coding games in Lisp, in case
you're into books. :)

On Thu, Mar 29, 2018 at 6:45 PM, Will Duquette  wrote:

> I'm an experienced programmer, but a Clojure newbie; as a beginner
> project, I'm looking into how one would idiomatically write a text
> adventure of sorts in Clojure.  I'm less interested in producing a playable
> game than I am in learning how to do such a thing in a proper functional
> style.
>
> Suppose in this game I have a room whose description changes based on a
> global flag.  For example, there's something in the Fancy Room that you
> won't notice until you've reached the major plot point.
>
> The world map is (for the sake of argument) a hash-map whose keys are the
> room IDs and whose values are room records, where each record is a hash-map.
>
> (def world {:fancy-room {:name "Fancy Room" :description "This is a fancy
> room." ...}})
>
> I'm aware that I could use a (defstruct) or (defrecord); I'm keeping it
> simple for now.  Then, the flags are saved in a ref; the intent is that
> mutable set is segregated, so that it can more easily be written to a save
> file.
>
> ;; Global set of flags
> (def flags (ref #{})
>
> (defn flag-set [flag]
>(dosync (alter flags conj flag))
>
> ;; When the major plot point is reached
> (flag-set :major-plot-point-reached)
>
> Normally, to describe a room you just return its :description.
>
> (defn describe [room] (:description (world get room)))
>
> But for the :fancy-room, the returned description depends on the global
> flag, and it will be specific to :fancy-room.  I could add this logic
> directly to the (describe) function's body, but that would be ugly.  What
> I'd like to do is attach a lambda to the :fancy-room in some way.  The
> (describe) function looks for a :describer, and if it's there it calls it;
> and if not it just returns the :description:
>
> (defn describe [entity]
> (if (:describer entity)
>   ((:describer entity) entity)
>   (:description entity)))
>
> *Question 1*: this works, but it looks ugly to me; I figure there's a
> better, more idiomatic way to do this kind of thing that's probably obvious
> to anyone with any real experience.  Multimethods, maybe?  Define a Room
> protocol, then let most rooms be NormalRoom records, but let :fancy-room be
> a FancyRoom record?
>
> *Question 2*: Whatever code actually computes the description, it will
> need access to the :major-plot-point-reached flag.  What's the cleanest way
> to give the description code access to the flags ref?  It could simply
> access "@flags" directly:
>
> (if (:major-plot-point-reached @flags)
>   "This is a fancy room.  Hey, that light sconce looks movable!"
>   "This is a fancy room.")
>
> But that doesn't seem properly functional.  Would it be better to pass the
> game state into each method?
>
> (defn describe [entity state]
>   (if (:describer entity)
>  ((:describer entity) entity state)
>  (:description entity)))
>
> Any ideas?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Proper way to write EDN file, after production bug

2018-03-30 Thread LaurentJ
I mean just print-dup and print-meta should be enough !

Le vendredi 30 mars 2018 14:31:04 UTC+2, LaurentJ a écrit :
>
> Yes we will set print-dup, print-meta, print-level and print-length to 
> have a properly formatted edn file.
>
> Le vendredi 30 mars 2018 05:55:50 UTC+2, Didier a écrit :
>>
>> Ya, I'd write a wrapping fn, like ->edn which internally binds everything 
>> to what it should be, maybe even declares some extra print defmethod if you 
>> need custom edn serialization, and returns the edn.
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Proper way to write EDN file, after production bug

2018-03-30 Thread LaurentJ
Yes we will set print-dup, print-meta, print-level and print-length to have 
a properly formatted edn file.

Le vendredi 30 mars 2018 05:55:50 UTC+2, Didier a écrit :
>
> Ya, I'd write a wrapping fn, like ->edn which internally binds everything 
> to what it should be, maybe even declares some extra print defmethod if you 
> need custom edn serialization, and returns the edn.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.