5 ms·
I still think this is a great appeal of Clojure(Script), you often work with the "flat" "just data" representations directly. From https://youtu.be/VSdnJDO-xdg?
by Jach 5y ago
I still think this is a great appeal of Clojure(Script), you often work with the "flat" "just data" representations directly. From https://youtu.be/VSdnJDO-xdg?t=3000 https://youtu.be/VSdnJDO-xdg?t=3000 (transcript: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ClojureMadeSimple.md https://github.com/matthiasn/talk-transcripts/blob/master/Hi...):
Example - HttpServletRequest
getAsyncContext, getAttribute, getAttributeNames,
getCharacterEncoding, getContentLength,
getContentType, getDispatcherType, getInputStream,
getLocalAddr, getLocale, getLocales, getLocalName,
getLocalPort, getParameter, getParameterMap,
getParameterNames, getParameterValues, getProtocol,
getReader, getRealPath, getRemoteAddr, getRemoteHost,
getRemotePort, getRequestDispatcher, getScheme,
getServerName, getServerPort, getServletContext,
isAsyncStarted, isAsyncSupported, isSecure,
removeAttribute, setAttribute, setCharacterEncoding,
startAsync, startAsync...
getHeader, getHeaderNames, getHeaders, getIntHeader...
"How many maps?" Vs.
In Clojure, Just Use Maps
{:remote-addr "127.0.0.1",
:scheme :http,
:query-params {"somekey" "somevalue"},
:form-params {},
:request-method :get,
:query-string "somekey=somevalue",
:content-type nil,
:uri "/foobaz",
:server-name "localhost",
:params {"somekey" "somevalue"},
:headers
{"accept-encoding" "gzip, deflate",
"connection" "close",
"user-agent" "Apache-HttpClient/4.1.2 (java 1.5)",
"content-length" "0",
"host" "localhost:8383"},
:content-length 0,
:server-port 8383,
:character-encoding nil}
"In Clojure, we just use maps. This stuff came over a wire in HTTP, as
text. How did we turn it into this [the Java]?"
- Sinidir 5y agoThis will never cease to produce laughter in me :)
- eyelidlessness 5y agoThis is almost exactly TypeScript’s worldview at the type level. It’s just structural types. The only difference is that it’s statically analyzable as a core feature. JS is a little more complicated than that, but (sorry to tell you) so is ClojureScript, where a “map” can become a bunch of different actual data types through the course of a normal runtime. In all cases, sending plain maps/pojos is nice but receiving them is fraught. Again TypeScript helps here by providing type guards where your parse/validation code can be statically analyzed. Edit: and in terms of serialization, all of these languages struggle with fidelity loss. Clojure has EDN or Transit if you’re willing to incur one cost or another. But by default you’re sending out a smaller subset of types than your runtime is using, and receiving the same.
- fulafel 5y agoI'm guessing you mean it's similar to the map case? Clojure/Script of course approaches validation and parsing using schema systems (malli or spec) that has its advantages compared to static type based approaches.
- eyelidlessness 5y agoI mean TypeScript’s structural type system is effectively “just use maps”. With very few exceptions, any structurally equivalent type is substitutable for another. > Clojure/Script of course approaches validation and parsing using schema systems (malli or spec) that has its advantages compared to static type based approaches. So does TypeScript. It has to, because the type system doesn’t have a runtime. The benefit in TS is that you also get static analysis.
- fulafel 5y agoCan you point to some exemplar TS schema system(s) suitable for structured data parsing and validation? I've seen io-ts but it seems quite clunky in comparison, but maybe it's not representative.
- fulafel 5y agoReplying to myself - Zod seems a better TS side library for this.
- eyelidlessness 5y agoYes, I would have pointed to Zod. There are a lot of options in the space, but I think there’s still room for improvement. My (vaporware, but I’ve built something similar before on top of io-ts) project would provide a similar API, but with base types built from JSON Schema definitions, and automatically generate docs. There are also opportunities to significantly improve runtime performance (at the expense of build time) by avoiding unnecessary parsing where statically checked code paths are already valid, eg naive multiple parse steps.