Fork me on GitHub
#clojure
<
2018-03-28
>
foxlog00:03:46

how to use clj command to launch a repl and specify repl’s port? when man clj I found clj has a parameter: --repl , but where to specify port?

hiredman00:03:00

what kind of repl?

hiredman00:03:22

clj itself launches a repl, but not a network repl, so no port

hiredman00:03:56

clojure has a built in socket repl that you can cause to be launched by passing the right -D arguements to the jvm

hiredman00:03:26

a lot of tooling uses n(etwork)repl which is a different thing again

seancorfield01:03:42

@foxlog Here's my ~/.clojure/deps.edn file that provides aliases to start a socket REPL, a Rebel-Readline REPL, or an nREPL -- the first and last on port 5555 since I choose to hardcode that.

seancorfield02:03:00

I guess it would be nice to have some sort of environment variable substitution available in deps.edn but maybe that's moving too far out of scope of the intention of the tool... 🙂

pavani02:03:31

@camdez I am using using your sendgrid library to send email. Great lib by the way 🙂 But i'm having trouble sending emails to multiple recipients. Could you please help me with that? I don't really understand how to send it this way to[][email protected]&to[][email protected]

camdez02:03:23

@vellalpavani Happy to help. Let’s continue via DM. At a jazz bar right now but I’ll do what I can. :rolling_on_the_floor_laughing:

👍 8
Ykä08:03:57

I'm comparing the developer experience of PaaS offering of AWS, Google, Azure and Heroku with a Clojure & PostgreSQL example app. My plan is to create a blog post and a talk on the topic. Currently it feels like Heroku is winning this one: https://twitter.com/ykarikos/status/977995307370909696

👍 4
Fahd El Mazouni08:03:18

@yka do you know of a faas that supports clojure ?

valtteri09:03:56

@fahd.elmazouni well, if there’s a JVM you can run Clojure. Personally I’ve tried both Clojure (JVM) and ClojureScript (Node) on AWS Lambda. Some tooling exists also: https://github.com/uswitch/lambada https://github.com/mhjort/clj-lambda-utils https://github.com/portkey-cloud/portkey (aims to provide REPL-like development experience for writing AWS Lambda functions)

Ykä09:03:31

Yeah, I've heard people run Clojure on AWS Lambda, but haven't done it myself.

valtteri09:03:09

There’s also #aws-lambda but it’s been quite inactive recently

valtteri09:03:24

#portkey also

Fahd El Mazouni09:03:24

cool ! thanks ! do you think there might be a loss in performance ? if I run clojurescript on Node 6 ?

Fahd El Mazouni09:03:15

(sorry if I'm asking outside of the proper channel)

valtteri09:03:49

No problem. 🙂 I don’t know about the performance impacts but at least I haven’t experienced anything noticeable. My stuff hasn’t really been that perf-critical though.

Fahd El Mazouni09:03:03

okey thanks ! I'm trying to learn javascript the functional way ( for backend ) and I'm always under the impression I'm doing it wrong

valtteri09:03:15

If your going CLJS and Lambda, I’ve had good experience with this https://github.com/nervous-systems/serverless-cljs-plugin

Fahd El Mazouni09:03:05

Thanks ! I'll look into it

schmee10:03:26

@fahd.elmazouni if you want the deep dive on the subject, check out https://www.youtube.com/watch?v=GINI0T8FPD4

grease13:03:47

Regarding https://danielcompton.net/2018/03/28/clojure-survey-2018 . We probably shouldn't be overly navel-gazing as a community. However, couple of themes seem recurrent in consecutive surveys: (1) Error messages should be better (2) pace of language development should be better. I'm curious about the core-team's thoughts on these.

john13:03:25

As a "community member" I disagree with (2) and think that may be more of a condition that is pathological to all language communities. Plus 1 for error messages.

Alex Miller (Clojure team)13:03:38

1) agree 2) we work at the pace we work

john13:03:12

@mailgrease that's a really interesting article though and there's a lot of takeaways

john13:03:26

One thing I wonder: what if you plotted the number of messages in #jobs #remote-jobs etc? I could be wrong but it seems like the number of jobs is increasing rapidly.

Alex Miller (Clojure team)13:03:42

the Clojure job market seems very strong right now to me

👍 4
john13:03:04

I see at least one new job offer a day

john13:03:08

half remote jobs

john13:03:31

I mean, across my various info channels

gabriele13:03:52

could you point me to your info channels? i'm actively looking for a clojure job. thanks 😃

john14:03:42

Well, I use feedly. There's a convenient search feature in there that let's you automatically pull in RSS feeds from related sites.

john14:03:52

Or make google alerts on keywords

john14:03:28

And then there's all the jobs channels in here. And of course the "functional jobs" website and the clojure jobs on clojure brave and true site.

john14:03:58

you can also add your name here: http://www.clojureconsultants.org/

gabriele12:03:51

thanks 🙂

mpenet13:03:47

For 2. it does feel like some tasks could be directed at the community with a little direction and decent feedback loop.

mpenet13:03:25

I am sure there are some moderately low hanging fruits at least that could be solved that way

mpenet13:03:01

but yes, can't complain much otherwise

john13:03:45

I think 'core' team hasn't wanted to play favoritism towards tools and methods for a long time. Which is why they let lein and boot have free reign. But I think some more control would help too

manutter5113:03:57

Definitely feel like error handling ought to bubble up to the top, and I feel like spec has the potential to make some really useful error messages possible. I don’t feel like there’s any problem with the pace of development.

Alex Miller (Clojure team)13:03:12

I personally do not believe in the idea of “one way to do it”. I think we as a community should consider everything, try new things, and always be searching for a better solution.

Alex Miller (Clojure team)13:03:42

It is imo not the core team’s job to choose and promote a single stack for web development for example

👍 60
Alex Miller (Clojure team)13:03:13

The pace of core language development is slow, or said another way “Clojure is a very stable language and my code works the same over many releases”.

💯 4
Alex Miller (Clojure team)13:03:53

As Rich has said “Clojure is a small language, and intends to remain so”

👍 20
manutter5113:03:51

That’s a good thing.

👍 28
schmee13:03:54

I agree with what tim baldridge said in the reddit thread: > Personally I would love it if new development on Clojure almost completely stopped, and instead development focused on fixing the lacking features in spec, the weirdness transducers (when is (fn []) of a transducer called?), all the problems with core.async's semantics, and in general just polished the coded added in the past 4 years.

20
schmee13:03:32

personally, I would like to add "bring the compiler up to speed with new JVM improvements" to that list 😉

Alex Miller (Clojure team)13:03:49

we’re not going to stop trying to solve important problems

schmee13:03:19

I don't think that's what he's saying, and that not what I mean either

Alex Miller (Clojure team)13:03:37

I think it is exactly what you’re saying “I would love it if new development on Clojure almost completely stopped”

Alex Miller (Clojure team)13:03:05

I would like to have a more even budget of time on maintenance level work

Alex Miller (Clojure team)13:03:02

and that’s something we have been trying to figure out for a long while

schmee13:03:05

if I would be equally uncharitable in my interpretation, I could say that you just said "fixing bugs and maintenance is not an important problem that we want to solve"

20
schmee13:03:30

but let's not argue semantics. allow me the rephrase the statement as "on the scale of new features and maintenance, let's take a slight step towards maintenance" 🙂

Alex Miller (Clojure team)13:03:10

take a look at http://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html though - we look at votes as one signal for which bugs people care about (and fix many of the highest ones in each release). There are only 3 defects with 10+ votes. There are certainly bugs to fix in Clojure but I think it is actually pretty rare that you encounter bugs in Clojure that prevent you from getting your work done. spec is definitely an area where we have some known issues right now and I very much hope to get back to it soon.

john13:03:45

I don't know. Seems like Tim is already getting what he wants...

john13:03:21

Not a ton is being added to core clojure these days

Alex Miller (Clojure team)13:03:37

Tim had the opportunity to spend any Friday he wanted at Cognitect working on Clojure or core.async maintenance

Alex Miller (Clojure team)13:03:23

I think he still has commit rights on core.async and I’d welcome his help on the backlog

tbaldridge15:03:25

Eh, I have commit rights, but not rights to actually do development 😄 Any questions of semantics and bugs in core.async have to go through the long drawn-out process of any other patch to Clojure libs.

Alex Miller (Clojure team)15:03:49

that’s not entirely true in core.async

Alex Miller (Clojure team)15:03:18

I have asked him repeatedly to help on specific areas where he is the expert and he has chosen not to

tbaldridge15:03:02

Yes, I got tired of the process and the lack of direction in the library. I even asked for permission to have more control over the library and was told "we got it from here". I loved working on the library when we had rapid iterations, feedback between team members, and clear direction as to where the library needed to head. But today it's a toolbox of features that each differ a bit in semantics. Things like close! semantics are still open-ended. Some are propagated down, some aren't. Some primitives allow for upward propagation, others don't. I got tired of asking for input on these things. So when I was told it was moving into core for better management I said "Great! I wish you luck" and walked away.

bronsa14:03:59

if everybody that's ever contributed to clojure has burned out from it, there must be a reason

bronsa14:03:20

repeating that there's no problem when clearly an increasingly number of people (most of whom are past contributors) think there is, is not going to make it go away

Alex Miller (Clojure team)14:03:18

what do you think would make the biggest difference?

john14:03:21

what does "burned out" mean?

bronsa14:03:47

@alexmiller not having a bus factor of 1

bronsa14:03:29

you guys are doing an incredible job with the resources you have

16
bronsa14:03:35

but it's clearly not enough

8
bronsa14:03:55

people have been offering to help out for years

bronsa14:03:05

and help gets turned down

bronsa14:03:14

i don't know what more the community can do to solve this

Alex Miller (Clojure team)14:03:40

when I do ask for help, people rarely do

manutter5114:03:43

"help gets turned down"?

bronsa14:03:26

@alexmiller that's because people are not willing to help when somebody else's asks for it, they're willing to help when they have time and will for it

bronsa14:03:57

if I keep offering my help and it gets turned down, and then you go "hey, please help now", I don't have time or will to invest more time now, I had it for the past 6 years

john14:03:16

I just made a few contributions to cljs. It was pretty easy. I can understand if I made a big change and it didn't get accepted, how that could be frustrating. But look at the constant contention with linus torvalds and the linux community. Does anyone thing that this developer contention will ever go away? Or that it's necessarily a bad thing?

bronsa14:03:17

(not talking about myself here)

bronsa14:03:34

@john cljs is a different story

Alex Miller (Clojure team)14:03:54

you run multiple contrib projects autonomously and have 38 commits in Clojure

Alex Miller (Clojure team)14:03:02

how are we not accepting your help?

john14:03:05

Yeah, and I have much less desire to change clj though in any way

bronsa14:03:05

yes, I was not talking about myself, it was an "impersonal I"

bronsa14:03:22

and honestly, I accomplished that despite of how hard it was

bronsa14:03:25

and it's because I am obsessive about getting what i care about accepted

bronsa14:03:29

most people are not like that

Alex Miller (Clojure team)14:03:20

everyone wants to bikeshed how the code is formatted but very few want to go fix that gnarly compiler bug that takes a week (you excluded Bronsa :)

john14:03:25

well I think this is healthy contention that should exist in a language community. People passionate about what should or shouldn't be in there

bronsa14:03:44

really, I'm not trying to attack anybody here but I'm baffled at seeing how this issue that every serious contributor notices, is not being taken seriously even after all those years

bronsa14:03:23

@alexmiller and can't that be because they know that it will take them 4 more years until it gets merged, and they'll have to rebase it 15 times, and fix all the merge commits that happen meanwhile etc

bronsa14:03:29

because that's why people don't do it

bronsa14:03:05

not because people don't want to help

Alex Miller (Clojure team)14:03:13

I don’t ask people to merge and rebase patches - I usually do that for people. I realize that Clojure’s development rate requires a long view and there is not the satisfaction of immediate gratification you get from a project that merges PRs every 5 minutes. I’d like to make changes that find a middle ground but Clojure is always likely to favor proactive “important” work over reactive “urgent” work.

bronsa14:03:02

eh, if the patch goes stale it's usually not considered for review IME

Alex Miller (Clojure team)14:03:05

I update patches for tickets all the time - I only ask for help with that if it’s drifted so far I can longer update.

bronsa14:03:38

I guess the type of patches I work on cause me to have a different perspective than most contributors then

Alex Miller (Clojure team)14:03:46

that is probably true :)

john14:03:06

I don't know, it seems like one day a "Clojure Foundation" sort of thing will be inevitable, when Rich one day wants to retire or whatever. But as a community member, for my vote, I'd prefer our BDFL carry the ball down the field as far as humanly possible before that inevitable bureaucracy sets in.

4
gtrak14:03:07

that sounds like 'what other people think is urgent isn't urgent'

gtrak14:03:23

or it's at least confusing, I'm not sure how you can call something urgent and also deprioritize it

Alex Miller (Clojure team)14:03:35

modern OSS development is imo incredibly destructive (to people’s lives) in creating expectations for rapid turn around on every problem

👍 8
12
Alex Miller (Clojure team)14:03:18

and the result of this is that oss devs often spend 99% of their time merely reacting to things rather than actually doing good software development

dominicm14:03:44

The latest round of react changes sound like they will fulfil this.

dominicm14:03:03

I scowl when I see such things.

bronsa14:03:44

I absolutely agree

bronsa14:03:48

but there must be a middle ground

Alex Miller (Clojure team)14:03:10

by “urgent” I mean “I want this now” not “something is on fire”

schmee14:03:15

even Java, the eternal bastion of stability, has moved to a 6-month release cycle with extended support for every third(?) release

schmee14:03:24

maybe Clojure could adopt something similar

schmee14:03:36

not saying we should, just putting the idea out there

Alex Miller (Clojure team)14:03:18

and the result of this is that oss devs often spend 99% of their time merely reacting to things rather than actually doing good software development

rauh14:03:05

@alexmiller I understand that Clojure itself wants Jira + Patches (which is already a hurdle for some) since RH has stated it clearly: https://groups.google.com/forum/#!msg/clojure/jWMaop_eVaQ/3M4gddaXDZoJ Though, what I don't quite understand: Why are all sub-projects also on the Jira+Patches track. E.g. I'd imagine you get much more contribution and help if TDEPS (and many other projects) was just 100% github. (Like the CLJ/CLJS websites). I'd imagine this would allow you (and others) to spend more time on CLJ itself. Just a thought...

gtrak14:03:44

^ I was also just going to suggest splitting more stuff out and experimenting with process there.

rauh14:03:21

Point being: I guess RH doesn't vet tickets on TDEPS, so why the extra hurdle of Jira+Patches?

Alex Miller (Clojure team)14:03:42

jira+patches is imo a completely orthogonal and unimportant issue

Alex Miller (Clojure team)14:03:58

if making a patch is a barrier to contribution, then you’re not very serious about contributing

jcf14:03:45

@alexmiller have you tested that theory out?

Alex Miller (Clojure team)14:03:26

I have used both jira/patch and github/pr approaches heavily

jcf14:03:31

Not trying to have a go at all. Just curious and wonder what I can do to help.

jcf14:03:37

If anything.

bronsa14:03:47

I mean honestly, how hard is it to git format-patch and attach a patch

bronsa14:03:57

that's not the issue

bronsa14:03:12

it's not ideal, but it's a very minor inconvenience

Alex Miller (Clojure team)14:03:22

I spend 75% of the time understanding a problem, 24% of the time making a solution, and 1% giving it to someone

jcf14:03:26

@bronsa for someone who's done it before not difficult at all. But I know I've worked with people who don't know much about Git but could still contribute some Clojure code.

bronsa14:03:40

there's instructions on the wiki that you can literally copy paste

rauh14:03:18

Certainly true for Clojure project. But --sticking with TDEPS--, I'd imagine you'd just get much more help. Fixing a simple docstring e.g. I'm not going to spend 5min on Jira. But might do a quick PR entirely on github.

Alex Miller (Clojure team)14:03:41

or you can just make an issue

rauh14:03:48

Again, I'm not talking about Clojure. But the other much smaller projects.

Alex Miller (Clojure team)14:03:49

and I’d make the change for you

🚌 4
Alex Miller (Clojure team)14:03:21

the aversion to jira and patches is irrational

denik21:03:06

that’s right, but it’s known that people prefer what is familiar

mpenet14:03:45

so not really an issue imho

bronsa14:03:59

it's not an issue at all and it's just distracting from the real issues when people keep talking about it

👍 36
bronsa14:03:32

moving clojure contrib to github PR is not going to solve any of the issues people have with the contrib process

rauh14:03:42

My argument was: It'd free up time for work on Clojure itself for Alex. Since the smaller projects would see more community contributions.

Alex Miller (Clojure team)14:03:00

I spend 0% of my time on this stuff

bronsa14:03:18

if you think the problem is that alex is spending all his time making docstring patches, you're entirely missing the point

jcf14:03:05

@bronsa care to elaborate and list the issues you perceive?

bronsa14:03:29

I'm sure this is well meant and all, but this jira/PR thing is just useless bikeshedding

bronsa14:03:37

@jcf I've already done so in the reddit thread

bronsa14:03:52

I've left several comments

jcf14:03:22

@bronsa I may have missed some of your points, but a quick skim showed mislabelled issues (enhancements that you consider to be bugs) and not enough people working on Clojure. You said people are driven away when they try to contribute somewhere as well I think?

rauh14:03:02

I disagree, when I look at tdeps commits: Then 99% of the 422 commits are done by Alex. That was code he had to write. My hypothesis is: If this was on Github entirely then that number would look different. Less work for Alex => good thing.

bronsa14:03:12

please, I've written quite exhaustively about what the issues I think are in that thread, I'm exhausted from weeks of acute insomnia and don't have the strength to repeat myself here

bronsa14:03:40

just read those comments

bronsa15:03:50

@rauh no that's nonsense, that's alex working on new tdeps features, not alex fixing bugs in tdeps that some community member could do

rauh15:03:29

Why shouldnt the community be able to implement new features? The core team can also create issues and let the community come up with PRs for them.

Alex Miller (Clojure team)15:03:56

they can and have. this discussion makes no sense in the context of tdeps.

bronsa15:03:22

the issue is that because alex is just one person, he can only work on one project at a time -- what we'd need is a way to scale contributions/bugfixing horizontally rather than having a bus factor of 1 for clojure and of 3 for most core projects

rauh15:03:39

I agree with you. But I'm realistic enough that I know the bus factor of clojure wont change anytime soon. Hence my idea trying to at least get other projects more into community hands. It'd be a start

bronsa15:03:17

because features are not developed openly, and the cost of getting the community up to speed with the design process would outweight the benefit of having more people working on it

gtrak15:03:31

If the process has too many tickets, why not just close all the tickets? I bet many potential contributors visit some, maybe upvote or something (you have to create an account first), but I think years old tickets are less honest wontfixes.

bronsa15:03:47

not necessarily

bronsa15:03:10

we regularly get patches in clojure for tickets that have been in jira for over 5 years

bronsa15:03:35

that's just because there hasn't been time/interest in looking at them earlier, not because they're not important

gtrak15:03:42

you don't think that affects prioritization?

bronsa15:03:11

sure it does, but you're making it sound more significant than what it is imo

bronsa15:03:18

look at the most voted clojure tickets

bronsa15:03:25

look at how long some of those tickets have been open for

bronsa15:03:22

old tickets == implicit wontfix is just a false equivalence

gtrak15:03:14

I think reducing latency per ticket would create a lot of transparency and reduce some community frustration.

gtrak15:03:00

Core could resurrect a few per release cycle that are actually being worked on, without making any promises. It seems like there might be easy wins there without really adding to the mental load.

seancorfield16:03:42

Late to the discussion (because I'm on the West Coast 🙂 ) but my position is that the slow development of Clojure is a feature, not a bug: it provides amazing stability for serious production use. The number of things we've had to change in our code base over seven years of production use, due to breakage caused by new features and/or other changes in core, is very small... maybe as many as one thing a year. That's incredible and radically different to most other languages/tech stacks.

28
👍 8
seancorfield16:03:02

The number of blocking bugs over those seven years has also been vanishingly small.

seancorfield16:03:36

And on community contribution, as someone who has been doing OSS development for about 25 years (I know, "Gramps!"), with a variety of processes, I'll say that when the barrier to entry is very low, you do indeed get more contribution but that also takes up a lot more of the project maintainers' time because the quality of some of that contribution is lower. You get into long back-and-forth discussions about PRs for all sorts of reasons. The GitHub/PR process can cause a lot of friction because the burden is switched from contributor to maintainer -- you get PRs for a lot of stuff you don't want to change (whitespace/formatting) along with things that should have been discussed as issues first so the contributor is on the right page. Reviewing, discussing, and rejecting PRs all takes time that a higher barrier tends to protect the maintainer from.

☝️ 4
zentrope16:03:43

For prototyping, I'd like to run multiple Clojure services in the same JVM. Maybe one is a simulator, another is an API/query service, a third serves up a clojurescrapt app, etc, etc.

zentrope16:03:04

Is there an obvious approach to that, say, with a library, as opposed to me mastering ClassLoaders and so on?

zentrope16:03:20

And NOT the old web-container, WAR way of working?

mattly16:03:05

you could do it with Component, Mount or Immutant, with some jiggery-pokery

zentrope16:03:28

Maybe that's the key.

zentrope16:03:46

A separate service called "System" that just launches the others, present on the class path.

zentrope16:03:38

(Mind you, I'm not saying this is a good idea. Just curious. And Docker weary.)

hiredman16:03:25

I do that with component a lot

qqq16:03:22

I need a Java GUI that can render a 120 rows * 100 cols of text on every keystroke within 30 ms. Should I go with Graphics2D, JFrame, some Terminalr Emulator, or something else

zentrope16:03:43

hired man: I like integrant, but it seems like a good idea. Maybe even with deps.edn and the relative local/root thing, I could get it working more simply than I expect.

gtrak16:03:07

@seancorfield I think there ought to be other ways to make noise easier to ignore instead of increasing the barrier for everybody. That seems like a blanket justification for any process, intentional or unintentional.

gtrak16:03:58

like for example, closing tickets

john16:03:06

@zentrope if the purpose of running multiple services on the same jvm is to avoid boot time latency, there's things like drip: https://github.com/josteink/lein-drip

hiredman16:03:33

it is useful for tests

zentrope16:03:07

@john Well, this is just for allowing folks to check out a repo with several services (that I like to keep separate) and start them all at once. Could also just use fancy shell scripts. Not so worried about start-up.

hiredman16:03:13

e.g. if I have a service that operates as a cluster and I went to test that they reliably do stuff even when the network is flakely, I can create two systems in a single jvm (because component packages all the state locally instead of having global state), swap out the network communication for a core.async channel with a buffer that drops msgs 10% of the time, and run tests

zentrope16:03:48

@john My one curiosity is class loader isolation (like web containers have) for mix and match libraries (which is not really an issue I don't think for me specifically).

zentrope16:03:11

@hiredman That's a great idea.

zentrope16:03:43

Boot had some sort of "pod" thing...

boot-clj 4
john17:03:18

socket repls are pretty cool here too

seancorfield17:03:42

@zentrope You don't need Boot's pods for this (in general) tho' -- you can just start multiple components in a single JVM. As @hiredman says, that's what we do at work: start the component for each service and start the component for your tests (or have your tests start the appropriate components directly).

zentrope17:03:27

This isn't about testing (mainly demos and prototype), but acknowledged.

zentrope17:03:49

What about different services with conflicting dependencies?

zentrope17:03:11

Well, I guess I'll just wait for that problem to happen.

john17:03:25

Yeah, I'm fuzzy on the class loader stuff, but I believe class loader isolation for multiple processes in the same jvm was explored and was considered hairy

john17:03:24

cemerick went down this road with pomegranate: https://github.com/cemerick/pomegranate

zentrope17:03:26

I think web app containers / app servers (tomcat, jetty, etc) do that for war files. Each WAR gets its own class loader for its own dependencies, etc.

zentrope17:03:49

Right! The boot-pod stuff uses some of that.

orestis17:03:39

I also like the fact that Clojure is not a moving target. I can understand though that there seems to be a need for a community catalyst of sorts to help improve tooling. I hope that Clojurists Together plays that role.

orestis17:03:42

Regarding the core team’s role, I was jarred at first with how easy Alex and David (the most well-known core people for me) say no. It clicked later though, and I’d rather we get a solid ground we can build on from the core team. Much better use of their time.

Alex Miller (Clojure team)18:03:23

no is temporary, yes is forever

orestis17:03:04

Here’s a nice turn of phrase I caught on Twitter just now: https://twitter.com/andy_matuschak/status/979019076038094848

orestis17:03:49

I’d rather the core people have a long/medium term to advance the language/programmer experience than get caught up in the bustle.

justinlee17:03:55

Although it is very good to take stock of the advantages of any given approach, I think some of this is a false choice. You can have a stable language and a good developer experience at the same time if you engage with the community well. Learning to say “no” more nicely would be a good start.

👍 4
the2bears17:03:46

The comments on elitism are ones I just can't see. From my own experience this has been the most friendly, most helpful community I've seen.

👍 12
orestis17:03:38

Same here. Though I believe that different venues might have different tones. Slack and Clojureverse are really kind, balanced and friendly. Reddit might be sometimes a bit rougher.

michaels18:03:33

The clojure redit is nothing as elite as /r/java.

eskos18:03:47

Curiously the newest members (who are also newest to Clojure from us) of my team did agree with the elitism part.

eskos18:03:06

They reflected it heavily to the lack of basics teaching in form of tutorials and other similar content and a general unease of even daring to ask the simple stuff.

eskos18:03:45

Also the amount of swearwords about the documentation has been like sailing with captain Haddock at times.

john18:03:18

Yeah, the elitism thing might be a projection of one's unfamiliarity. The tower doesn't seem as ivory-ish, once you're able to start reading the actual core source code

orestis18:03:45

Oh, I was thinking about how I felt around 10 years ago. I didn’t dare ask anything online lest I appear stupid. Perhaps there’s something there — no matter how friendly the community is, if people have to ask something, there will be a % that will be turned away.

the2bears18:03:10

Yeah, r/clojure seems pretty tame, too, but it is a little rougher at times. It has a small troll content at times, or maybe that's my bias 🙂

orestis18:03:00

@suomi.esko What background do those team members have? I’ve tried writing an intro to Clojure on my blog but it’s really hard to “tune” the tone.

eskos18:03:17

@orestis Varies a lot, but generally more junior - as in a few years of software engineering experience tops with related university studies/maybe a degree.

eskos18:03:55

They're on the level that when I explained threading macros the first time it blew their minds 🙂

orestis18:03:02

Coming from a Java background? Or from a dynamic language?

eskos18:03:20

Well, the other of the two people I'm thinking here comes from JavaScript background. The other I'm not even sure, actually.

justinlee18:03:47

You folks sure are working really hard to say, “these problems don’t exist so we can ignore them”

8
eskos18:03:47

(now you made me look)

orestis18:03:00

That’s a bit harsh @lee.justin.m - I’ve already written half my intro to clojure blog post, starting from scratch, and I want to get an idea what makes people stumble.

the2bears18:03:39

@lee.justin.m which folks are you talking about?

justinlee18:03:05

The very first reaction to “people on my team see it this way” is “gee they must be junior and/or just not get functional programming”. Seriously. Just think about how that reads.

eskos18:03:38

My general tips would be that don't assume - formal education - understanding of category theory or set theory or any other similar high level concepts - understanding of functional programming and what it entails (I once spent an hour talking about persistent data structures to a crowd and afterwards I was thanked how amazing idea the whole "data stays the same" thing is) Also don't use fancy words. No one gives a frying duck what a monad is 🙂

the2bears18:03:58

"What background do those team members have?" does not sound like "gee they must be junior"

the2bears18:03:22

Unless I've missed a comment.

justinlee18:03:29

Okay I stand corrected. I take it back. I don’t want to cause hard feelings here.

eskos18:03:14

Whenever I try to talk about concepts I assume that someone's just seen a cool thingamajig, grabbed it and come to me asking "What's this? :D". That is, start low - when you get to know your audience you'll learn soon what you can assume and skip.

orestis18:03:19

As long as we get to discuss, no hard feelings from me. There’s obviously some nuance here that must be nailed down.

the2bears18:03:24

Well, you're right though that we should be cognizant of these things. And it's often the case I don't see things as others might justifiably see them due to my own biases and perspective.

eskos18:03:58

(tangentially, I wish http://clojuredocs.org would just plain simply replace the official api documentation)

seancorfield18:03:30

Folks, this discussion has moved away from the technical -- which is what #clojure is for -- and into community, so it really should move to #community-development /admin

👍 16
hiredman18:03:53

What I experience is many new comers sort of think they know everything and get mad when something comes along that exposes their ignorance, which is silly, no one knows everything

4
hiredman18:03:11

and as a high school drop out with no formal cs education besides a javascript class or two at the local community college, I find the notion of elitism kind of laughable

john18:03:44

You're our resident elitist and we like it that way 😉

hiredman18:03:07

every teacher in the world is apparently elitist

john18:03:30

I'm going to make a clojure derivative called "leet," just to settle it once and for all 😉

sundarj18:03:45

i've a similar background to you hiredman, and also see no elitism. perhaps it's a case of hammer/nail?

the2bears18:03:16

I did when I was a teenager 😉

the2bears18:03:21

But not now...

seancorfield18:03:33

(and, yes, I contributed to that earlier instead of pushing the conversation over to #community-development -- which is what I should have done two hours ago!)

orestis18:03:56

Point taken @seancorfield - unfortunately I need to go but please continue on the other channel. It’s good to get these things out in the open.

seancorfield18:03:39

Yes, definitely a healthy discussion to have.

ghadi18:03:58

regarding Error Messages: I'd like a tool that interprets stack frames -- not just an error "prettifier". We should be able to cook up something that was able to make a determination: "Something threw an exception while realizing an item in a lazy-sequence" you can glean all this info from a stacktrace -- there are well-defined signatures in the clojure runtime. (for example, since clojure 1.8 there is now an invoke and invokeStatic trace element for every core call -- just need to show one!)

ghadi19:03:30

this would be very useful to beginners

ghadi19:03:59

(btw, such a hypothetical tool does not belong in Clojure itself)

stuarthalloway19:03:03

+1000 @ghadi! Such a tool should be a web service, with client added at the REPL

stuarthalloway19:03:34

I always imagined its name being wtf?

👍 12
schmee19:03:07

that's a really cool idea

john19:03:45

@ghadi would this be orthogonal to spec?

ghadi19:03:40

totally separate

john19:03:13

could it then be combined with an expound like thing?

ghadi19:03:30

but there is an analogy here: expound:explain-data :: wtf:Throwable->map

john19:03:51

does one not obviate the other?

john20:03:10

like, if I have wtf, do I still need expound?

ghadi20:03:27

wtf would be only for interpreting stacktraces specifically. expound is for prettifying spec's explain-data

john20:03:57

ah, right

john20:03:18

so they could be combined into a singular error reporting interface

ghadi20:03:17

keep it separate. Though it would be nice to have a community "distribution" of clojure that made it easy for beginners. Preconfigured expound + wtf, etc.

8
sundarj20:03:04

i've been thinking this too; would deffo be up for contributing to it.

ghadi20:03:35

community-made

john20:03:29

yeah, as long as the seem consistent with respect to each other, spec error reporting vs stacktraces. Yeah, if you've got a plan to go forward on that, I'd definitely help hack on it.

ghadi20:03:34

I don't have a plan, but I'll dust off my hammock

john20:03:49

I guess you'd have to decide whether to use a db of known stack trace heuristics or to dynamically pull names out of the classes at runtime that we find from lines in the stack trace?

ghadi20:03:03

a db of heuristics for sure. I think that's what Stu was alluding to.

john20:03:43

Yeah, for a webservice, for sure

ghadi20:03:43

something that could be contributed to, got better with time

john20:03:17

Well, you're also pushing your stack traces out to an external service on every throw

john20:03:40

which not everyone in every situation will want to leverage

john20:03:19

But if lots of people did that, yeah, we'd have some serious data to build heuristics on

ghadi20:03:47

should be on-demand, not automatic. Readme should make it clear that it is a potential security leakage

ghadi20:03:38

But you don't have to have data to start -- can do standard stuff like this and build some rules: (doall (map #(throw (Exception. "foo")) [1 2 3]))

john20:03:44

dang, if we end up pushing an LSTM into devops...

jaydeesimon20:03:45

question about vars and metadata…

jaydeesimon20:03:53

doing this works fine

jaydeesimon20:03:58

user=> (-> identity var meta)
{:arglists ([x]), :doc "Returns its argument.", :added "1.0", :static true, :line 1443, :column 1, :file "clojure/core.clj", :name identity, :ns #object[clojure.lang.Namespace 0x2d1dee39 "clojure.core"]}

jaydeesimon20:03:15

how would I accomplish something like this?

jaydeesimon20:03:18

user=> (map (fn [f] (-> f var meta)) [identity])
CompilerException java.lang.RuntimeException: Unable to resolve var: f in this context, compiling:(NO_SOURCE_PATH:4:14)

sundarj20:03:54

@jaydeesimon var is a special form; it happens at compile time. to do it at runtime you use resolve:

=> (map (fn [sym] (-> sym resolve meta)) ['identity])
({:arglists ([x]), :doc "Returns its argument.", :added "1.0", :static true, :line 1443, :column 1, :file "clojure/core.clj", :name identity, :ns #object[clojure.lang.Namespace 0x44c43989 "clojure.core"]})

jaydeesimon20:03:38

ah ok - thank you. what if I have a reference to the function and need to turn that into a symbol? (so that I can pass it to resolve)

sundarj20:03:32

no official way to do the reverse i don't think

sundarj20:03:51

you could maybe try parsing (str f)

jaydeesimon21:03:03

ok cool. good to know. thank you

seancorfield21:03:23

To get you started

user=> (clojure.main/demunge (str +))
"clojure.core/+@42bc14c1"
user=> (defn foo [] 42)
#'user/foo
user=> (clojure.main/demunge (str foo))
"user/foo@13518f37"
user=> 

seancorfield21:03:43

If you str/replace #"@.*" with "" you should have something you can feed to symbol and then resolve I think.

seancorfield21:03:47

(it won't handle anonymous functions tho')

sundarj21:03:55

i think (.getName (class f)) also does the trick

seancorfield22:03:44

Indeed! That looks a better path than (str f)

user=> (clojure.main/demunge (.getName (class +)))
"clojure.core/+"
user=> (clojure.main/demunge (.getName (class foo)))
"user/foo"
user=> (clojure.main/demunge (.getName (class (fn []))))
"user/eval162/fn--163"

jaydeesimon22:03:17

this is great stuff - thanks again

ghadi20:03:29

you can't

seancorfield21:03:23

To get you started

user=> (clojure.main/demunge (str +))
"clojure.core/+@42bc14c1"
user=> (defn foo [] 42)
#'user/foo
user=> (clojure.main/demunge (str foo))
"user/foo@13518f37"
user=> 

MegaMatt21:03:19

I wrote my first clojure program, i am hoping to have someone with experience tear it up with brutal honesty about what is bad, what is weird, and suggestions to do things differently. If anyone is interested in helping I can send you some LTC for the trouble. PM me if interested, i'll be back on later tonight.

seancorfield22:03:47

@matthewdaniel Do you want to post it on #code-reviews ?

MegaMatt23:03:48

sorry, didn't know that was a channel

PB22:03:17

Maybe a stupid question. I'm trying to use spec/fdef to validate the inputs to a function. I have come up with the following:

(s/def :my.ns/meow string?)

(s/def ::meow-spec (s/keys :req [:my.ns/meow]))

(s/fdef meow
        :args (s/cat :some-map (s/coll-of ::meow-spec
                                          :kind map?)))

(defn meow
  [some-map]
  some-map)
However. I am a little confused as to how this works.
(s/valid? ::meow-spec {:my.ns/meow "a"})
=> true

(s/valid? ::meow-spec {:my.ns/meow 1})
=> false

(clojure.spec.test.alpha/instrument)

(meow {:my.ns/meow "a"})
=>
ExceptionInfo Call to #'harmonium.edi.handler/meow did not conform to spec:
In: [0 0] val: [:my.ns/meow "a"] fails spec: :harmonium.edi.handler/meow-spec at: [:args :some-map] predicate: map?
  clojure.core/ex-info (core.clj:4739)
What am I doing wrong?

bbrinck22:03:04

@petr Do you perhaps mean :args (s/cat :some-map ::meow-spec)

PB22:03:42

At that point, it's not being explicit about it being a map though?

bbrinck22:03:05

s/keys only works for maps

PB22:03:32

So coll-of ... :kind map? only works if you don't care of the contents in teh map?

bbrinck22:03:39

Generally, you won’t want to use coll-of ... :kind map?. The only thing that’s valid there is a spec that describe key/value pairs, IIRC (I haven’t needed to use this form, although it can be useful in certain circumstances)

bbrinck22:03:48

generally, you’ll want map-of or s/keys

bbrinck22:03:41

But the most important thing in the example above is that the spec says: “args must be a single element collection, the first element of which is a map, which contains maps”

bbrinck22:03:12

I think you just want to say “args must be a single element collection, the first element of which is a map with key :my.ns/meow

PB22:03:46

Hmmm OK. That makes sense. I should probably also just look into map-of. Thank you

bbrinck22:03:23

Cool. In this case, I think you can just get away with s/keys since (s/valid? ::meow-spec []) ; => false. At least from your example function call, I think you are intended to just pass a map, not a map of maps

bbrinck22:03:32

In any case, good luck!

PB22:03:52

Sorry one more question. It's kind of frustrating to have to call (clojure.spec.test.alpha/instrument) everytime I re-evaluate my ns. I sthere a way around this?

PB22:03:05

I've found if I do not, it does not activate the fdef

bbrinck22:03:44

As far as I know, there is not a way around this. I wonder if this could be integrated into some editors

bbrinck22:03:57

i.e. a keyboard shortcut for “eval and re-instrument”

PB22:03:04

That is probably very doable

PB22:03:22

At run-time this check will be running though?

bbrinck22:03:40

Only if you call instrument

bbrinck22:03:06

keep in mind that instrument will only check the args, not the :fn or :ret spec. That’s a common misunderstanding

bbrinck22:03:33

There’s a library called orchestra that changes this though. I recommend it 🙂

PB22:03:36

Aw man, thts kinda disappointing

bbrinck22:03:13

The good news is that orchestra is really easy to set up. Just replace [clojure.spec.test.alpha :as st] with [orchestra.spec.test :as st] and call st/instrument as usual

PB22:03:41

So if I have to call it either way, why is one better than the other?

bbrinck22:03:33

oh, sorry, I misunderstood your response. i thought you meant the behavior of instrument was disappointing, but you meant that you had to call it repeatedly

bbrinck22:03:15

The difference between orchestra instrumentation and default instrumentation is that orchestra will check your “return” and “function” specs

PB22:03:20

Well my understanding is either way. To have run-time validation of my args, I need to call instrument

bbrinck22:03:54

that’s correct. the only difference is whether the fdef specs for return value and function are checked

bbrinck22:03:17

i.e. the :ret and :fn specs, respectively

PB22:03:31

So those functions inside of clojure.spec are just... For docs?

bbrinck22:03:26

Those specs are checked when you call clojure.spec.test.alpha/check

PB22:03:46

Ah so during testing

sundarj22:03:33

see here: https://clojure.org/guides/spec#_instrumentation_and_testing >>>Note that the :ret and :fn specs are not checked with instrumentation as validating the implementation should occur at testing time.

lwhorton22:03:36

if I have a macro in a macro, which macro is evaluated first? in-> out or out->in?

PB22:03:57

My guess would be in -> out

lwhorton23:03:25

Hmm. puzzling. I have someone elses macro doing stuff:

(some-other-macro vals {:some-data (my-macro some-arg)})
But when I macroexpand this what I expect to get is:
(... {:some-data (my-expanded-macro stuff)}
But what I get instead is just
{ ... {:some-data (my-macro some-arg)}}

sundarj23:03:56

it's up to the outer macro how the forms passed to it get evaluated

lwhorton23:03:19

so an outer macro can prevent an inner macro from expanding?

mfikes23:03:21

An outer macro can do anything

lwhorton23:03:50

so I would have to write a macro that invokes this macro AFTER expanding any macro forms inside the args?

bronsa23:03:06

macros are evaluated out->in

mfikes23:03:08

An outer macro can conditionally decide whether some inner macro is left alone to be evaluated, or is discarded, or an entirely new form involving other inner macros is used

bronsa23:03:37

@lwhorton needing to do that is usually a sign that you're doing some quite complex macro, for instance core.async's go kinda does that

bronsa23:03:55

so I would reconsider why you need to do that if I were you

lwhorton23:03:30

hmm .. it isn’t complex, it’s just trying to “fix” someone elses macro from a library

lwhorton23:03:23

such that I can use a simple macro (get-var some-symbol) which will be converted at compile time to some constant like “400px” or “blue”

(var-get (ns-resolve 'css.vars (symbol sym)))

lwhorton23:03:36

except my get-var color, for example, when used inside another macro, doesn’t actually expand to “blue”-- so it should be possible to just write a macro that wraps the other guy’s macro and first macroexpand-all’s on the arguments, then invokes the inner macro with the newly expanded args, right?

lwhorton23:03:53

huzzah!

(defmacro defstyled [sym element styles]
  (let [expanded# (clojure.walk/macroexpand-all styles)]
    `(cr/defstyled ~sym ~element ~expanded#)))

sundarj23:03:53

just pointing out, that # doesn't actually do anything

sundarj23:03:46

expanded# is literally expanded#, since it's not within a syntax quote

lwhorton00:03:13

:thumbsup: macros are hard

sundarj00:03:01

well, you don't need syntax quote to write a macro 🙂

sundarj00:03:39

could write it as

(defmacro defstyled [sym element styles]
 (let [expanded (clojure.walk/macroexpand-all styles)]
   (list 'cr/defstyled sym element expanded)))

lwhorton00:03:12

yea, i like the ` and ~ as visual indicators though

sundarj00:03:03

fair enough

lwhorton00:03:33

still cant really get what I want, for some who-knows reason:

(defmacro get-var
  "Mixing clj and cljs namespaces doesn't work at runtime. We have to have a compile-time
  solution for referencing static variables from a cljs namespace in other clj or cljs
  namespaces for styling purposes. For example, we need vars defining font sizes, break
  points, etc. This macro will compile-time expand the given symbol into the requested
  value (as defined inside this vars namespace)."
  [sym]
  (var-get (ns-resolve 'css.vars (symbol sym))))

(defmacro defstyled [sym element styles]
  (let [expanded (clojure.walk/macroexpand-all styles)]
    `(cr/defstyled ~sym ~element ~expanded)))

#_(macroexpand '(defstyled foo :bar {:color "pink" :nested {[[:max-width (get-var medium)]] {:color "red"}}}))

lwhorton00:03:48

if you evaluate the bottom #_ form, everything works handy-dandy as expected

lwhorton00:03:20

but if I’m outside of this namespace and invoke defstyled, it still refuses to expand (get-var medium)

lwhorton00:03:36

i don’t see why a separate namespace matters at all

sundarj00:03:12

the way macros work in cljs it does matter, but i'm iffy on the details

lwhorton00:03:45

hmm ill have to dig around for that

sundarj00:03:29

i'm seeing the same behaviour in Clojure

sundarj00:03:36

boot.user=> (macroexpand '(defstyled a b (when true)))
(cr/defstyled a b (if true (do)))
boot.user=> (in-ns 'foo)
#object[clojure.lang.Namespace 0x7e93e1b2 "foo"]
foo=> (clojure.core/macroexpand '(boot.user/defstyled a b (when true)))
(cr/defstyled a b (when true))

sundarj00:03:25

think that's just how macroexpand works, for whatever reason?

sundarj00:03:16

i presume that actually running the macro will fully macroexpand

lwhorton00:03:41

yea it doesnt seem to, though. when I look at the generated text at runtime its still “{:max-width (get-var medium)“. 😕

4
lwhorton00:03:02

hard part is knowing if this is a cljs vs clj difference, an incorrect macro, a namespacing problem, or something else

sundarj00:03:31

well it happens in my clj repl, so it's not a clj/cljs thing (as i first incorrectly assumed). but it's still very curious

sundarj00:03:07

probably worth asking in #clojure now 😛

lwhorton00:03:17

can someone comment on why changing into a namespace separate from where a macro is defined makes macroexpand’s behavior change?

sundarj00:03:02

foo=> (clojure.walk/macroexpand-all '(boot.user/defstyled a b (when true)))
(cr/defstyled a b (when true))
foo=> (clojure.core/use 'clojure.core)
nil
foo=> (clojure.walk/macroexpand-all '(boot.user/defstyled a b (when true)))
(cr/defstyled a b (if true (do)))

sundarj00:03:23

the macros have to be defined in the current ns

sundarj00:03:13

makes sense

darwin00:03:19

what is cr/defstyled? why don’t you use fully qualified name?

lwhorton00:03:43

cljss.reagent/defstyled, to be precise

darwin00:03:51

then slap it here

lwhorton00:03:47

my intent is to totally avoid any of the complexities of this lib, and simply fix the problem that it doesn’t accept values with macro expansion in the styles arg

sundarj00:03:06

referring get-var into the ns you're using your defstyled from should fix it

lwhorton00:03:47

i wish that did it, tried that like an hour ago to no avail

lwhorton00:03:53

so from a cljs namespace, :refer-macros [defstyled get-var] still spits out (get-var medium)

darwin00:03:02

could you share your boot.user/defstyled again?

lwhorton00:03:18

(defmacro defstyled [sym element styles]
  (let [expanded (clojure.walk/macroexpand-all styles)]
    `(cljss.reagent/defstyled ~sym ~element ~expanded)))

darwin00:03:37

why do you use cr there? use fully qualified name

lwhorton00:03:50

(defmacro get-var
  [sym]
  (var-get (ns-resolve 'css.vars (symbol sym))))

darwin00:03:52

ok, now it looks good

lwhorton00:03:57

and css.vars (for completeness)

(ns css.vars)

;; break points
(def medium "768px")
(a .clj file, though this shouldn’t matter I don’t think since it’s compile time)

darwin00:03:34

let my try to reproduce it here on my machine

sundarj00:03:02

fwiw, using cr/defstyled should be fine:

foo=> (require '[clojure.string :as str])
nil
foo=> `str/x
clojure.string/x

lwhorton00:03:13

well, if I have my css.vars defined as a .cljs file-- expansion even in the same ns where macros are defined results in get var

lwhorton00:03:34

so that’s … something. I guess it has to be a clj file in order for var-get to work.

lwhorton00:03:14

well, sorry to dump this and run but I have to get going for now ill be back later

darwin01:03:05

run it with ./demo.sh

darwin01:03:48

this is pure clj code, the cljss.reagent/defstyled macro emits cljs code, but that is not important

darwin01:03:19

if you really want to define your constants in cljs then clojure code cannot help you, but you can have another macro which emits clj-defined constants as constants in cljs code, this way you can access them from cljs code, but that would be more tricky to setup

darwin01:03:53

have to go as well, good luck

lwhorton14:03:16

so there’s 3 differences here I can see. 1 is the namespace invoking the macro is clj, 2 is there’s no cljs compilation step, 3 is just using the clj cli tool instead of lein w/ figwheel

darwin16:03:47

well, I wanted to create minimal case, that is why I didn’t introduce lein or cljs

lwhorton16:03:23

yea I appreciate that, i was just thinking aloud

lwhorton16:03:58

i really wish there was just a short-cut to tell the compiler at read time “go look up this symbol and inline it”

darwin16:03:18

macros are clojure functions which rewrite code into another piece of code, typically they rewrite clj code into clj code, or cljs code into cljs code, but in this hybrid case, they rewrite code which has simple clj expressions (your constants) into cljs code

darwin16:03:12

“the compiler” is ambiguous here, do you talk about clojure compiler or clojurescript compiler?

darwin16:03:39

macros are compiled by clojure compiler and see clojure state of things

darwin16:03:14

and that is what we are doing there, we are looking up symbols in clojure compiler state and inlining them

lwhorton16:03:59

i mean the clojure compiler that sees a macro and rewrites the values. i just cannot seem to get clj to look at a macro used in a cljs file and swap out the values (defined in another clj file) properly

darwin16:03:21

aren’t you expecting it to inline cljs values? if you wanted to look up cljs symbols, your would have to inspect clojurescript compiler state and get it from there, which is more complicated

darwin16:03:08

" a macro used in a cljs file” is not special from my point of view, it just emits cljs code

darwin16:03:35

but it runs in clojure environment, so it can look only at clojure state (under normal circumstances)

darwin16:03:36

…or modify that minimal case with your problem and I could look into that

lwhorton16:03:46

if the values are defined in a .clj file, though, as simple (def my-val "foo"), wouldn’t a cljs file that invokes a macro still have access to my-val during the clj compilation?

lwhorton16:03:37

in this sense the macro is just emitting cljs code, and the code it emits does a var lookup from another clj file.

lwhorton16:03:02

it makes no sense to me why the ultimate output of a macroexpand-all is still (get-var my-val) and not "foo"

lwhorton16:03:17

i appreciate all your help by the way, i guess at the end of the day I have a foundational misunderstanding somewhere that’s blinding me

darwin16:03:38

sorry, didn’t see your replies, “emitting cljs code” and “the code it emits does a var lookup from another clj file.“, second sentence does not make sense. cljs code cannot see “clj world”. and cljs code (at runtime) cannot do something like a “var lookup” AFAIK

darwin16:03:53

what you can do is to write a macro, which when expanded in cljs code emits some data from clj world, for example resolving some values and inlining them into cljs sources

darwin16:03:38

that was my proposal, if you wanted to re-use those clj constants (css.vars) in cljs code, you could write macros which would emit them into cljs code

darwin16:03:15

…and then you could use them in normal cljs code

lwhorton17:03:48

that’s exactly what I want to do

lwhorton17:03:02

if I had a simple macro like this:

(defmacro get-var
  [sym]
  (var-get (ns-resolve 'css.vars (symbol sym))))

lwhorton17:03:34

at compile-time from clj, would this not replace (get-var some-symbol) where (def some-symbol "hello") with (... {:some-val (get-var some-symbol)}) -> (... {:some-val "hello"})?

darwin17:03:53

in cljs code you can write (def some-symbol (get-var some-symbol))

darwin17:03:00

get-var is a macro

darwin17:03:08

it expands to “hello”

darwin17:03:29

so final result in cljs code will be (def some-symbol "hello")

darwin17:03:41

or something along those lines, you could have a macro which will walk css.vars namespace and generate cljs code which will def each var in cljs and inline corresponding clj value there, for example

lwhorton17:03:25

i was just at the wrong call site the whole time - should be defining a symbol via the get-var, not at the cljs space

darwin17:03:09

this macro stuff is really confusing if you don’t really understand how it works internally, mainly the important fact that macros are clj functions which rewrite code and see only clj state

darwin17:03:39

but it gets more complicated than that 🙂 think about self-hosted cljs, in that situation macros are actually cljs functions

darwin17:03:31

and you can have a cljc file which acts differently under different conditions…

darwin17:03:18

try to look at clj and cljs code as different languages, they happen to be very similar, but in these cases you really should understand “where you are”

darwin23:03:06

yes, if the outer macro needs to work on expanded code then it needs to expand it as part its own work, e.g. to use macroexpand-all

lwhorton23:03:43

is expand-all a “proper” way to handle this, or is it only intended for use as a debugging tool? i.e. should I be dipping into the tools.analyzer?

lwhorton00:03:17

can someone comment on why changing into a namespace separate from where a macro is defined makes macroexpand’s behavior change?