This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-02-28
Channels
- # announcements (30)
- # architecture (9)
- # aws (2)
- # babashka (23)
- # beginners (55)
- # cider (22)
- # clj-kondo (40)
- # clojure (47)
- # clojure-europe (4)
- # clojure-france (2)
- # clojure-italy (17)
- # clojure-nl (16)
- # clojure-norway (1)
- # clojure-sanfrancisco (1)
- # clojure-seattle (1)
- # clojure-spec (12)
- # clojure-uk (34)
- # clojured (3)
- # clojurescript (15)
- # core-async (11)
- # cursive (19)
- # data-science (3)
- # emacs (7)
- # events (4)
- # figwheel-main (10)
- # fulcro (33)
- # graalvm (49)
- # graphql (11)
- # instaparse (1)
- # java (7)
- # kaocha (1)
- # leiningen (7)
- # malli (3)
- # meander (69)
- # pathom (9)
- # re-frame (4)
- # rum (2)
- # shadow-cljs (34)
- # spacemacs (9)
- # sql (29)
- # tree-sitter (1)
- # yada (3)
hello all, i am reading "Living Clojure" and i found it quite clear, although there are things that i still don't understand and are not explained in the book... for example... why if clojure pushes for using basic native data types (such as lists/vectors/maps and so on) it has things like defrecord and stuff like that... i mean how and when should i use those? from what i understand defrecord and similar are used to define new type of data right?
Things like defrecord can be handy when you’re working with protocols or multimethods because you can dispatch on data type. You could achieve a similar effect by including a :type
key in your map and dispatching on that, but using records can be a bit cleaner.
defrecord is faster for one. At some point when your code matures you find it slow you may replace some of the datastructs with records. records are more familiar to those wanting to strongly type their code. Also keep in mind that clojure is excellent at retaining backwards compatibility, so you will find some things in it that you may wonder why they are there. And they are kept there so old code that was written to use them continues to work. And example of this is defstruct.
There are also applications where you’re doing things with Java interop, and you need to keep track of Java types, so there’s support for that in Clojure too.
Hey everyone. Im trying to write something just to get familiar with clojure so I wanted to write a really simple server. but I can't seem to figure out what exactly clojure wants in the :accept
key of start-server
(ns clojure-noob.core
(:require [clojure.core.server :as http])
(:gen-class))
(defn mine
[]
("Hello World")
)
(defn -main
[& args]
(http/start-server {:port 4040 :accept clojure-noob.core/mine :name "localhost" :args []})
(while 1)
)
The error
Exception in thread "Clojure Connection localhost 1" java.lang.ClassCastException: class clojure_noob.core$mine cannot be cast to class clojure.lang.Named (clojure_noob.core$mine is in unnamed module of loader clojure.lang.DynamicClassLoader @4d4d8fcf; clojure.lang.Named is in unnamed module of loader 'app')
at clojure.core$namespace.invokeStatic(core.clj:1597)
at clojure.core.server$accept_connection.invokeStatic(server.clj:73)
at clojure.core.server$start_server$fn__8864$fn__8865$fn__8867.invoke(server.clj:117)
at clojure.lang.AFn.run(AFn.java:22)
at java.base/java.lang.Thread.run(Thread.java:830)
clojure-noob.core/mine is being resolved to the actual function that is defined under that var
start-server doesn't want a function, it wants a name that it can look up a function with
to send the name (symbol) clojure-noob.core/mine you can tell clojure not to resolve the symbol by quoting it. (quote clojure-noob.core/mine)
or shorthand 'clojure-noob.core/mine
Ok i sort of follow that. different error now who when I don't resolve the symbol and just quote it.
Exception in thread "Clojure Connection localhost 5" java.lang.ClassCastException: class java.lang.String cannot be cast to class clojure.lang.IFn (java.lang.String is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed module of loader 'app')
at clojure_noob.core$mine.invokeStatic(core.clj:7)
at clojure_noob.core$mine.invoke(core.clj:5)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.core$apply.invokeStatic(core.clj:665)
at clojure.core.server$accept_connection.invokeStatic(server.clj:73)
at clojure.core.server$start_server$fn__8864$fn__8865$fn__8867.invoke(server.clj:117)
at clojure.lang.AFn.run(AFn.java:22)
at java.base/java.lang.Thread.run(Thread.java:830)
I figured. dosen't want to call a string as a function or something?
ooh ok.
ok. let me try to fix that.
ok so Im not getting errors anymore but im also not getting a response. so I did this
(defn mine
[]
#([] "Hello")
)
Stupid question. would I be able to hit this on a browser at localhost:4040 and get a response or is that just not what this thing does at all
yea. same thing. no errors but no output.
cool thanks maybe ill try telnet or something. Im actually not sure how SocketServer works if itll respond to http. thanks for the help @hobosarefriends @bfabry
that seems like at least it connects tho so thats cool
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 23812 xxxxx 12u IPv6 0x2e93801b0a183315 0t0 TCP localhost:yo-main (LISTEN)
➜ prevention-point git:(master) ✗ nc localhost 4040 -v
nc: connectx to localhost port 4040 (tcp) failed: Connection refused
nc: connectx to localhost port 4040 (tcp) failed: Connection refused
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif lo0
src 127.0.0.1 port 58002
dst 127.0.0.1 port 4040
rank info not available
TCP aux info available
Connection to localhost port 4040 [tcp/yo-main] succeeded!
from the doc string clojure.core.serve/start-server
:accept Namespaced symbol of the accept function to invoke, required
. Note that this is not a normal http server
Yea it was the description of symbol that was confusing me. Im still not really sure what a symbol is. Is there something equivalent to an http server? ive seen https://github.com/ring-clojure/ring
Right. I was looking to see if there was something built into clojure tho that was simple to stand up but thats fine. Any clarification you can give on the symbol definition?
no web server built into clojure i don't believe. I'm looking for good documentation on symbols so i don't give you a handwavy explanation
Thank you. Yea Im reading the docs on http://clojuredocs.org/clojure.core/symbol
there are java sockets, which are kind of "built in" to clojure. lot of work to get to a web server from there though
actually the http://clojure.org/reference/reader gives a decent explanation
@bfabry Yea I was mostly just curious to see how you really import and create stuff with the clojure libraires so really just trying to be able to read the docs, understand it and call something
Having some working http server actually wasnt the goal in the end
http://clojure.org/reference is great documentation. reading it all would do anyone a world of good. fwiw this answer shows how to use clojure + java sockets to listen to a port and respond with a string from a repl https://stackoverflow.com/questions/60121687/how-can-i-get-clojure-to-write-a-response-to-a-socket/60122704#60122704
yea I started with Clojure for the Brave and True but ive been flipping around the reference docs. Thanks again
@me1159 there is a relatively simple example of building a server-side web app here http://practicalli.github.io/clojure-webapps/ and I did some more recent videos walking through building a server-side web app and API https://www.youtube.com/watch?v=IoGWbM6Wqeg&list=PLpr9V-R8ZxiCe9p9tFk24ChNSpGfanUbT
@me1159 You may also find this small example (of Ring, Compojure, Component, Selmer, and next.jdbc
) helpful https://github.com/seancorfield/usermanager-example
I’ve seen “Ring” mentioned a lot. What is that? (The new draft specs for it just came out.)
ring is a specification for mapping http request/responses to function calls passing clojure data
Others who actually know can correct/refine this, but basically a de facto standard among Clojure libraries to pass data about HTTP requests/responses between functions.
similar to how java servlets are a specification for mapping http request/response to objects and method calls
one of the most commonly used ring implementations is ring-servlet which is an implementation of the ring spec on top of the servlet spec
Ring has a "default" adapter which is an embedded Jetty server, which is suitable for production usage, but can be used with several other servers (we've run both Jetty and http-kit at work).
super cool