- 57
- 164 112
Clojure/north
Canada
Приєднався 23 кві 2019
Canada's annual Clojure conference held in Toronto!
Come check it out, eh?
2020: June 25th-26th
2019: April 19th-20th
Come check it out, eh?
2020: June 25th-26th
2019: April 19th-20th
More Powerful Multimethods - Cam Saul (Q&A)
More Powerful Multimethods - Cam Saul (Q&A)
Переглядів: 460
Відео
Duckula: Type Safe Backend Services with Clojure, HTTP & Avro - Łukasz Korecki
Переглядів 5384 роки тому
Duckula: Type Safe Backend Services with Clojure, HTTP & Avro - Łukasz Korecki
The REPL as a General Purpose Tool - Wesley Matson
Переглядів 6504 роки тому
Some of us fight production fires using the REPL, even for non-Clojure projects. Each experience yields a useful script as an artifact. With a smidgen of forethought, these tools we build for ourselves can be shared and reused in creating investigative tooling for our teams.
Parens for Python Q&A - Carin Meier & Chris Nuernberger
Переглядів 3384 роки тому
Parens for Python Q&A - Carin Meier & Chris Nuernberger
Clojure Katas - Designing Data-Driven DSLs - Rafal Dittwald & James Cash
Переглядів 2,8 тис.4 роки тому
In recent years, there’s been a wave of new Clojure libraries written with “data driven” APIs. Be it routing, database-querying, or composing systems - problems that were once solved with string-, function- or macro-based DSLs are now being re-solved in a new “style” that’s somewhat unique to Clojure. What does it mean to be "data driven"? Is it just a fad? Is it only for libraries?
Building Marvelous and Heroic Systems from the Ground Up - Mark Bastian (Workshop)
Переглядів 1,4 тис.4 роки тому
Clojure is a fantastically powerful, yet simple language. Despite this assertion, it is not uncommon for those new to the language to have a hard time grasping how to build complete applications from the basic building blocks of Clojure. This workshop will bridge the gap from the basics of data literals all the way to building a complete, stateful web backend application. Participants will lear...
Data Diffing Based Software Architecture Patterns - Huahai Yang (Q&A)
Переглядів 2044 роки тому
Data Diffing Based Software Architecture Patterns - Huahai Yang (Q&A)
Concurrency with Clojure - Kapil Reddy & Rhishikesh Joshi (Workshop)
Переглядів 4104 роки тому
Concurrency with Clojure - Kapil Reddy & Rhishikesh Joshi (Workshop)
Clojure Katas - Functional Programming - Rafal Dittwald & James Cash
Переглядів 1,1 тис.4 роки тому
There’s more than one way to solve a problem. This workshop is an opportunity to step out of your Clojure bubble and see how other Clojure developers approach and solve programming challenges.
Evolving Code Through Accretion - Wilker Lucio (Q&A)
Переглядів 1564 роки тому
Evolving Code Through Accretion - Wilker Lucio (Q&A)
Gluing Clojure Microservices - Alexander Fertman (Q&A)
Переглядів 1904 роки тому
Gluing Clojure Microservices - Alexander Fertman (Q&A)
Introduction to Lambda Calculus - Asaf Chelouche
Переглядів 1,2 тис.4 роки тому
Introduction to Lambda Calculus - Asaf Chelouche
Software, but not as we know it: Part Two - Dann Toliver
Переглядів 5304 роки тому
Software, but not as we know it: Part Two - Dann Toliver
Duckula: Type Safe Backend Services with Clojure, HTTP & Avro - Łukasz Korecki
Переглядів 6904 роки тому
Duckula: Type Safe Backend Services with Clojure, HTTP & Avro - Łukasz Korecki
ClojureScript on Microcontrollers - Mike Fikes
Переглядів 3 тис.4 роки тому
ClojureScript on Microcontrollers - Mike Fikes
The Language of the Language: Comparing compiler construction in Clojure and F# - Ramsey Nasser
Переглядів 3,9 тис.4 роки тому
The Language of the Language: Comparing compiler construction in Clojure and F# - Ramsey Nasser
Building Reliable, Scalable Services with Clojure and Core.async - Kapil Reddy
Переглядів 1,1 тис.4 роки тому
Building Reliable, Scalable Services with Clojure and Core.async - Kapil Reddy
Debugging Clojure Services Under Stress - Paul Lam
Переглядів 4964 роки тому
Debugging Clojure Services Under Stress - Paul Lam
Unleash the Power of the REPL - Dana Borinski
Переглядів 1,6 тис.4 роки тому
Unleash the Power of the REPL - Dana Borinski
Data Diffing Based Software Architecture Patterns - Huahai Yang
Переглядів 1,7 тис.4 роки тому
Data Diffing Based Software Architecture Patterns - Huahai Yang
TLA+ and Clojure, a Small Primer - Paulo Feodrippe
Переглядів 7834 роки тому
TLA and Clojure, a Small Primer - Paulo Feodrippe
Gluing Clojure Microservices - Alexander Fertman
Переглядів 1,1 тис.4 роки тому
Gluing Clojure Microservices - Alexander Fertman
Literate Stream Processing - Francisco Viramontes
Переглядів 1,4 тис.4 роки тому
Literate Stream Processing - Francisco Viramontes
Evolving Code Through Accretion - Wilker Lúcio
Переглядів 1,5 тис.4 роки тому
Evolving Code Through Accretion - Wilker Lúcio
More Powerful Multimethods - Cam Saul
Переглядів 1,5 тис.4 роки тому
More Powerful Multimethods - Cam Saul
Hassle-free reporting with Lumo - Dmitri Sotnikov
Переглядів 4764 роки тому
This talk will illustrate how doc-builder leverages Puppeteer via ClojureScript to generate HTML and PDF reports. github.com/yogthos/doc-builder/
Monoids and Software Engineering - Luke Meyers
Переглядів 4254 роки тому
Universal abstractions are an attempt to mold subjective abstractions into formalized pieces built out of composable mathematical atomic structures that have well defined properties. The monoid is a humble boring yet powerful entry into the world of universal abstractions for managing complexity in software engineering. Other than it's well known use case in being a parallel programming abstrac...
Step one: delete Clojure. Step two: use a real language, like SQL.
So at 42:43 you’re saying slectRandom() and playRandomStrategy() are both “pure”, and that’s just referring to inputs and outputs, because the second relies on the first to function? So dependencies are ok in pure functions, it’s just that lack of side effects within it?
During the talk, I forgot to make a comment about selectRandom() that I planned to make: selectRandom() is not pure, though it may look like it, because given the same inputs a pure function would always return the same output. If it doesn't, there must be some dependency on an external state. With selectRandom(), Math.random() has a hidden state managed by the runtime (due to how random numbers are generated on computer), or, it could be sampling the environment (an external state). This does also mean any function that uses selectRandom() is not pure. But then comes the "pragmatic" question - does it matter? In some cases, testing a function with implicit randomness requires extra work to ensure correctness and the solution is often to make it pure by storing a seed value explicitly and passing it into a function that uses randomness. Another common "hidden state" is function that deal with "now" functions (to get the current date time), such as, say, a function "nextMonday()". It relies on a hidden state, and it's a pain to test (will it work correctly on Monday? have to wait until Monday to check) - the solution is to always pass in a now value to such a function, so you can simulate any now. Pure functions are trivially testable functions.
This made me realize i should just double down on Go - I appreciate the honesty. Getting away from the JVM is a blessing.
what’s cool about this functional programming demo here is that it did not stress higher order functions or composition at all. it was just about managing state which is the hard part of a system.
How has situation with Clojure techstack changed since then? I'd like to know!
Hi
Nitpicking, the term "pure" is used incorrectly. The extracted functions don't have side effects, which is only one of the requirements of purity. Some of them are not deterministic, which is also a requirement for functions to be marked as pure.
Yes, I goofed on this. I made some last minute changes to the presentation, wanted to specifically mention this, but then forgot in the moment. Luckily, several people like yourself have pointed it out. :)
Love that man!
Amazing talk!
Great talk. Keeps it simple and gives one of the clearest, most pragmatic and easy to understand explanations of the key aspects of functional programming. I've done lots of React, some Haskell and I'm now learning Clojure for a new job. Made perfect sense to me.
58:00 - that's rather different. They just describe their API in data, then generate clients for it. It's similar to swagger. - That is very different to writing the program, the server itself as largely configuration driven. - and I think code is great, and if you try to put a lot in "configuration" at some point it will become much more work than it's worth. - Also, "configuration" is harder to write: usually zero intellisense, discoverability (+correctness) even harder than with just dynamic types ... - That being said, I really DO like configuration in VSCode - it has lots of intellisense etc. - It becomes a lot more usable then, but writing this for YOUR "dsl" becomes way, way more work again...
ok, if you consider considering making intermediate data structures "data driven" as in reagent / reitit , then that's great, yeah, I agree.
22:08 "...and deferring, well, well we'll get to deferring in a moment." LOL well played
hi, i think u lookin gud fam
also good talk
I'm not clojure programmer, just started to look at it, but this talk was very cool, and refactoring imperative to FP style was great however you made couple of bugs during this process: - newScores() adds just 1, not bountyCard - report() should skip initial state, there are no lastBountyCard and lastPlayedCards values for initial state (and lastState is not defined) - endCondition should be flipped (using not or length == 0) (and lastState is not defined) anyway, it was cool and I wish you have couple more talks where you show how to "transition to FP", thanks!
2022 -- enter AWS-CDK -- the snake bytes its own tail: AWS Cloud Development Kit (CDK) accelerates cloud development using common programming languages to model your applications.
Thanks Tommi!!
Great refactoring! Also, pretty cool categorization of methods to avoid side-effects! 😄
Don't quite follow why he suggests that having global state is considered to be having side effects - if the closure of the system is well defined then it's just a matter of organisation.
A function that makes use of a mutable variable from outside of it is not a pure function, but, often this is a fine/useful trade-off.
@@rafd that's only true if one restricts the closure of the function's inputs and output to the stack (which is just a piece of memory). If one allows the inputs and outputs to be located else where then you still have a pure function (but are using another piece of memory) - really it is tracking the closure carefully that makes a function pure or not, not the location of which piece of memory in time a value resides. The system and the function cannot tell the difference. Admittedly most functional languages don't track global variables in that manner - which probably also makes them needlessly complex - but there is nothing inherent in type systems that prevent them from doing that. I see it as a language design decision rather than a fundamental of purity and idempotence.
This is a nice tutorial, thanks. Inspired from you I have also start create a clojure course on youtube checkout on my channel ua-cam.com/video/f9VBkTpr5uc/v-deo.html
I think this is a historical talk. Do you agree !?
10:00:50 OK, folks reinvented PHP
Big floppy maps and vectors become a mess over time. Prefer composable piecewise functions which generate what you need clearly and nest those. You'll get MUCH more power that way and you don't enter the brittle realm of copy/paste nonsense inherent in *only* pure data structures. And if your structure changes you'll adjust it in 1 place vs ALL over your code peppered with literal data representations. An unbound map literal is just a more advanced version of "magic number" in your program. ;; Clarity through composition shows intention (make-house ; Generates vector to hold rooms (make-room "foo") ; Generates {:room "name"} (make-room "bar")) ;; Better yet (make-house (make-room "foo" "bar" "baz" "qux")) ; make-room now multiple arity with & rest ;; Floppy garbage [{:room "foo"} {:room "bar"}] ; What does this represent? A house? An office? A prison? Nobody knows!
Great talk, thank you for walking us through that. Is there a bug in the recur function? The end condition looks like it would end on the first iteration. Also, the recursive call to recur() doesn't have the last two parameters. It's ok if there's a bug, I just want to make sure I'm understanding everything. Thank you again for all this information!
Yes, you're right on both counts. The endCondition should either be negated in the recur, or changed to == 0 at its source. The recursive call is missing the extra parameters. (Powerpoint is not a good IDE :P )
lol, understood. Thank you for the response.
I wish I had cljs when I was doing ASM on Z80's and 8085's to control racks of equipment across RS232 UARTs 42+ years ago :) Nice work!
This talk is such a hidden gem, it's one of the very few I've got backed up locally just in case
Very helpful. Thank you very much
Thanks
This perfectly demonstrates how to tease the pure out of the impure, the thing I want programmers who haven't seen it to see. Thanks for taking the time to showcase it.
57:50 is just mind blowing
It's Amazing! Thanks for your work!
This is superb..
(❤️)
Great talk. Here's my takeaway from it Process of making code more functional (eliminating impure code) 1. move all impure stuff to the top (the top component or a top function that calls everything else) 2. refactor out pure code from the top func 3. reorganize all mutable states into one (global) state object. 4. A dispatch function to return a new state (instead of mutating) 5. [Extra] instead of keeping a mutable state object, use a states array to keep all intermediary states. The top function is just a function to turn out states. 6. [Extra] use recursion to eliminate loop and mutation of state
I like how he deferred defining the defer technique. Lmao, very clever.
For those who need a more detailed explanation of the GOPS: ua-cam.com/video/WUTc1AF3a0I/v-deo.html
Fantastic talk. Thank you very much.
"After overcoming a fear of brackets..." Is this a rational or irrational fear? Haskell doesn't need as many brackets, after all. Is the opening parenthesis really necessary? Can we replace the end parentheses by something simpler?
It’s irrational, there’s much more benefit to having parens than the superficial improvement of more complex syntax. That’s the essence of structural editing.
Haskell doesn't need many brackets, yet it is scary. Maybe the fear doesn't come from the brackets but from the unfamiliar. In "Data and Reality" (§10.2.21) there's a beautiful discussion of simplicity that warns exactly about that.
Wow I think it's the first time I really get what functional programming is all about. I still can't get fully on board with the recursions, the accumulation of function calls and the accumulation of useless state variables though. A question to UA-cam's functional programmers out there, would it be possible to specify, instead of state_k = f(state_k-1) something like state_k = f(state_k-1) and by the way store state_k where state_k-1 was because I don't need it anymore?
This is going to be language specific. Clojure has immutable, persistent data structures. When you modify a vector or list, it shares the memory that didn't change. When you change a map (which is what you use for data structures), the keys that didn't change are shared. It will still be more expensive than just mutating in place, but it isn't as expensive as literally allocating a new chunk of state and copying everything over. If you absolutely must mutate state for performance reasons in Clojure (measure before you do this), Clojure aims to be a pragmatic language and has great interop with the host (JVM for Clojure, JavaScript for ClojureScript), so you can just go with mutable state if you really, really need to. For Elixir/Erlang, it has the persistent, immutable data structures too, but you tend to organize your code by Processes, and all data is deep copied when it crosses the process boundary. This has certain benefits (e.g. each process has its own garbage collection), but also certain negatives - so you need to be careful of your process boundaries. I don't know much about the other FP languages.
yes - if you only have one reference to the prior state you can mutate in place (there's no-one else around who can see you doing that) - it's all about aliases
Yes, clojure has “loop” and “recur”. Essentially what you do is declare variables when you call loop with their initial values. Later when you call recur you pass the same number of variables as loop started with, and it repeats the loop with the new variables you’ve given it. So for your example (loop [[state_k initial-value]] ;; logic in here, just use state_k like a normal variable (recur f(state_k))) ;; rerun the loop logic with this new value bound to state_k Conceptually you only ever have one state_k variable, but behind the scenes it’s replacing the value and nothing is mutated. If you needed the previous state_k for whatever reason you would just include it in the loop with an initial value that makes sense, e.g.: (loop [[state_k initial-value] [prev_state_k nil]] ;; loop logic here (recur f(state_k) state_k))
Your valuable content deserves a better microphone ! ✌🏻
Question: did Smalltalk programmers realize all of this eons ago?
Pretty much yes - smalltalk is 90% functional and 10% OO by his description
22:14 “Minimize, concentrate and defer. What’s defer? Well, we’ll get to that in a moment.” Why am I the only one who thinks that was totally hilarious!? XD. (Great talk, BTW.)
You stole the comment from my fingertips.
You are not the only one, you never are. I hate this phrase. I am not going to say "Am I the only who hates this phrase?", because I am not.
@@inanitas I think his point is that there was no reaction from the audience. It seems possible that Rafal didn't even mean it as a Dad Joke, but it was a class-V Dad Joke.
Been said many times already but this is by far the best talk I've seen explaining functional programming. Thank you so much Rafal!
But Clojure is a lisp! You can make a data-driven DSL in a lisp by putting a quote mark before any lisp expression. It seems unfair to lump both lisp and Ruby meta-programming with JS fluent API style. Both are quite different by culture and appearance from JS where the fluent style is basically a way of working around the lack of good meta-programming features.
Yes, LISP-code-is-data, but parsing or generating valid LISP code is much harder than parsing or generating valid "data" (ie. the rules of valid Clojure code are much more complex than the rules of valid EDN). Re: lumping Ruby meta-programming with JS fluent API -- as a user of libraries in both, it felt similar, but the way it's achieved is different. But, I agree, it's sufficiently different, that I should make a seperate category for 'metaprogramming' vs fluent API. In a remixed version of this talk, I did make a distinction between 'macro-based' DSLs (ua-cam.com/video/8Kc55qOgGps/v-deo.html) but, in the future, I guess I'll need to add a 5th (metaprogramming).
Have you looked into etoys on pi. A smalltalk. You can attach a cam and gpuio support. Cool thing is that you can modify it to your needs, and very shrinkable. PhysicalSpace wise it's not bad
The meta programming system mentioned around @55:10 is this one: www.jetbrains.com/mps/ It allows defining different projections for the same source code
@22:35 is a very good advice about error messages
What is the point of this talk? You don't talk much about native Clojure library for deep learning, which does not exist (Cortex is still in early phase and has not seen a release since Oct 2017). If you rely heavily on Python libraries using a wrapper, why not just use Python? When you develop a piece of software you have to think about long term maintainability. How many Clojure developers would you find compared to Python developers? You need to show us what Clojure offers in the machine learning space that is not available in other languages. One of the zens of Python is "Readability counts." Compare that to 17:39, you could as well write in Assembly.
Wonderful talk. The big take-away for me was the three idiomatic "pillars" of functional code that was talked about: Minimize, Concentrate and Defer. I'll be remembering those. I think it's important to point out that the final functional code you ended up with could still organized in an OO style - that is, organize the functions with the data they operate on (methods), and make the methods pure. In fact, I think if you're forced to work in an OO language (like Java), favoring a 'functional-OO' style is still beneficial for all the reasons outlined in this talk.
It's a practice in some OO circle nowadays to have 'data objects' (structs with just data) and 'method objects' (no data, but methods that act on data objects; or if immutable, return new data objects; in effect, since these are just 'collections of functions' they are like Clojure's namespaces --- which fun fact, can be compiled down to a singleton object with methods).
@@rafd I'm going to have to give that architecture a shot on my next personal Java project.
Lots of people program like you outline. It's just harder, and less efficient, in languages that aren't written to support it. The libraries you use probably won't work like this either. Furthermore, separating out your operations that interact with the world from the rest of your code has been good OO practice for a long time. For example, it's very difficult to test a class that both reads a file and parses it, so those two things should be separated.
What I'm not clear on is how the method table is implemented (in clojure's standard multimethods) in terms of namespaces and loading/unloading. Is the method table located in the same namespace where the defmulti is located? i.e. when a defmethod is encountered (e.g. in a different namespace), what happens? It's possible to use defmulti and defmethods all in the same namespace, but that seemed to defeat part of the purpose of the potential modularity being gained, at least, comparing to how generics are used in SICP. Haven't seen much explanation of this (mainly about clojure's implementation of multimethods, i.e. the starting point for this talk). Nice talk though. Feel it's important to get exactly how clojure does it clear first, before going more complex.
Such a great talk !