The Bipolar Lisp Programmer (2007)
marktarver.com
marktarver.com
Focus is a precious, rare resource outside my control. Mainstream languages, made for collaboration in big teams rather than maximum personal freedom, soon impose restrictions that kill hyperfocus. The "unused variable is an error" is the most egregious of them that I hate with a passion. The separation between compilation and running is another that seemingly inescapable today. With languages like Lisp, I can code at the speed of thought from prototype to production.
These days tech is advanced by FAANGs, so no one cares about removing the safeties from our languages; this is the reason the focus-challenged among us still go back to Lisp and other lost languages (Forth, Smalltalk, Self) that have disappeared from the mainstream.
Rust, C++, Go, Python, etc. are good, but they're not made for us.
If you want the least amount of friction possible, install Racket and run DrRacket. Here's a tutorial: https://docs.racket-lang.org/quick/index.html and one to make web apps: https://docs.racket-lang.org/more/index.html
(I don't mean to disparage Clojure, I'm sure it's great, but a newbie needs something easy to get excited about, not having to mess with JDK and setting up Emacs)
Go with Lisp instead. Or OCaml. Both are purer and leaner than the JVM-addled morass that is Clojure.
When I am programming in Lisp, I enter a sort of zen like state where my mind becomes one with the problem. Now don't get me wrong. I can write a lot of Go, Python, Rust, what have you on some days when I am working on a good problem and there are no meetings to distract me. On some days, I can do this for 6-10 hours straight with little breaks. So I don't think I have the ADHD problem that the parent or the OP is talking about.
But I still have this nagging feeling with other mainstream languages that their tooling, their ecosystem, the breaking dependencies, the "making the compiler happy", the stupid language restrictions and such things distract me from my problem domain.
But not so with Lisp. With Lisp, it's just me, the problem, the algorithms to solve it and the code. Nothing else. It is a feeling of hyperfocus (a word you so rightly chose). For some reason I cannot get into that state with other languages and I could never understand why.
Your comment is on to something here and this might very well explain the zen-like hyperfocus feeling of immersing fully into the problem domain I get with Lisp.
Sometimes it's nice to shed all that bullshit and just create something.
Sometimes, only on languages with the least amount of syntax and semantics you're able to sculpt that fleeting idea you had. Inspiration is very delicate, and it doesn't take a lot for it to die down because you forgot to update npm and your Emacs config is borked.
> But I still have this nagging feeling with other mainstream languages that their tooling, their ecosystem, the breaking dependencies, the "making the compiler happy", the stupid language restrictions and such things distract me from my problem domain.
I can relate to this in a different way.It seems the vast majority of work today is not "the problem", per se, it's the interface that exposes the problem (or solution) to others. Shoving stuff in and out of format (JSON, SQL, etc.), marshaling the data over interfaces, or building UIs to expose and work with it, etc. The problem domains themselves, for a lot of systems, can be pretty simple.
But with CL, with the reader, and things like Emacs, a lot of that falls into the background -- with the caveat "as long as you're willing to work with native representations", i.e. S-expressions.
I have an "application" in CL, and it's 1500 lines of code. Outside of a couple prints for debug, there is no I/O. No user interface. Nothing. It's all "just code". It's all "just problem".
Meanwhile, I have a Java program I wrote. It wraps a 1000 line Java utility into a GUI. There's 4000 lines of code to present that GUI. It's a not quite fair comparison, as the entire purpose of the application is to expose this utility into a "usable form".
But, with Java and other languages, there's always going to be some level of that. With CL, again if it fits within the confines of the REPL and S-expressions, you get all of that "for free".
Trivial case with a simple Java command is you need some way to parse the command line options. Extended lambda lists give you that "for free" in CL. Named parameters, optional parameters, default values, etc. Arguably the entire point of the extended lambda list descends from their use within environments like Lisp Machines, where the function arguments WERE the "command line", and that's why its so robust. Those are all nice features when writing code, but they're really nice when you have to type stuff in all the time.
And this ability to not worry so much about external representation, and moving and converting data, instead just focusing on what's being done to the data, in native terms, it's very liberating.
There is no "impedance mismatch". Just code, just data, and code is data.
Either way this comment makes me want to try a LISP! I might give Clojure a go, I daily drive another alt-JVM language at the moment so it’s a natural choice.
As for treatments there basically isn’t one. Among other things I experimentally microdosed quetiapine against it (under the theory dopamine might be involved) under the supervision of a doctor which basically cured the visual distortion but not the pain, but I quickly built a tolerance and binned it off because the side effects aren’t great. Some people benefit from anti-seizure medications but not everyone and the side effects can also be bleak. Fortunately medical cannabis is legal in the UK and it’s very effective against the pain, the amount of unsuccessful things I’ve tried qualifies me for it and the pain’s only a problem on very bad days now. Coding with the monofur font helps me too!
Of course everyone has some noise in their visual system, a little bit of TV static isn’t necessarily indicative of disease. For reference I struggle to read when it’s bad, and my night vision is impaired quite a bit compared to what it was before so you’d definitely notice if it was problematic.
One anecdotal thing from support groups etc that makes me cautious is that while some people are born with it and some people contract it spontaneously later in life (this was my case), other people can contract it after taking various types of drug. Typically these are serotonergic drugs like antidepressants, psychedelics, and that sort of thing which aren't in the same category so it'd probably be okay but it's definitely possible I can make things worse as well as better.
Maybe there are business reasons to avoid less popular programming languages, but there aren't any programming reasons to avoid them. Maybe we should stop treating tools as if they were candidates for homecoming king and queen.
While most languages are akin to preparing a detailed blueprint and executing it (then stop to update the blueprint and try again), exploratory programming is like sculpture. You have an unformed mass full of unrealised potential, and you slowly carve it to shape.
The ADHD/Bipolar mind of the article isn't great at making plans, it's great at following its gut instinct, making shit up step by step.
Lisp enables this flow, but also Forth, Smalltalk, Self, etc., which I've been deeply obsessed with lately. Sadly, all we have today on the mainstream are basic REPLs which are a harmless, defanged version of these old environments promoting creativity and flow state.
Can you elaborate on that? I think you are saying that REPLs in other languages don't do what you can do in Lisp, but I don't think I know enough to fully understand why.
You start a fresh REPL session with a vague idea of something you want to build. You have good tooling that enables you to write code in your favourite editor and pipe it to the REPL through a socket. You write a couple of functions and send them to the REPL. You call them a few times with some test arguments, maybe define a couple global variables while testing, and realize one of the functions doesn't quite behave the way you want. You tweak the code and send it again to the REPL. The function is redefined and works properly now.
You're happy with what you have for now, so you save the entire current environment of the REPL, functions and global variables and all, into a file (called an image) on your disk. The next day, you come up with a great new feature so you load up the image and continue exactly where you left off yesterday, with all your functions and even global variables as they were defined previously. You add your new feature, all while testing and tweaking your functions interactively, and then you save the new environment into an updated image. Any other code that loads that image will be able to take advantage of your updated functions and variables now.
The power of lisp is not just the fact that there's a REPL — a lot of languages have that now. It's the ability to save and reload the entire current state of the REPL (interactively or programmatically), which enables the powerful interactive development that so many lispers, including myself, rave about.
It particularly resonates with me because I think so many project teams neglect the Developer Experience. In my opinion DevOps should be more about making coding, testing and deploying as frictionless as possible.
now it just seems like a hundred children you have to pacify and get to bed before you can even start working
In the end what you have is a base image, and then a set of code and instructions to transform that image into your runtime image, then you distribute that image as your "application".
I have never needed to do this, as all of my work has been utilitarian in nature, rather than some kind of monolith distributed to others. I simply load my code on to the stock image and go from there.
But even then, for folks that do that, they may well load up the stock image with useful and common, personal, utilities, and snapshot that. Their "application" is their essential working environment.
Smalltalk does, and Forth can work from this concept of an image.
Schemes tend to not be this way. They are interactive, but the image concept is not as ingrained in the Scheme world. Instead, it's more like doing development in something like Bash -- an interactive environment to be sure, but one that always resets to the baseline state and must be reloaded when started. There are certainly Schemes that can do this, it's just not as routine.
I was motivated to do this because I had a ton of linguistic and text data in my environment which back then took a little while to load. Now, I organize everything I do into small or sometimes tiny Quicklisp projects/libraries and that is much more convenient for me.
If you want to really get into image based programming, the open source Pharo Smalltalk is very good.
Because there's a problem I've run into several times when writing Lisp (I use SLIME): I decide to refactor some stuff, so I rewrite some stuff, maybe remove a function or two from the source as part of that. Things seem to be working fine. I save my .lisp files and then at some point end up restarting the Lisp process (often because McCLIM can be kind of flaky and lose its connection to the X server). When I go to load my code back in, I get errors, because oops I was actually still calling that deleted function somewhere -- it "worked" before because the old function was still hanging out in the image.
When I develop in a compiled language, I just accept that I'm going to be re-building the entire thing from scratch (equivalent to restarting the lisp process & re-loading the source files) every time I want to try a change; if I broke something, I'll find out the next time I run make/go build/whatever. When I'm developing in Lisp, and I'll freely accept that my Lisp dev flow probably isn't ideal, it's so easy to screw up but be unaware of it for hours if not days: I write some code, I'm happy, I close Emacs, then a week later I come back and try to load my package and it's just broken.
I could solve it for myself by just using images: the "deleted" function would persist in the image, and every time I started working again it would be there. But if I ever want to let somebody look at the code, hack on it, make changes, what's that look like?
"batch compiled from scratch"
OTOH, most usage of Common Lisp is compiled, often by an incremental in-image compiler
> because oops I was actually still calling that deleted function somewhere
Typically Lisp IDEs have features like Edit Callers and/or List Callers. I would
1) "Edit Callers" -> this walks me through all functions which use this function, I change the functions and I can edit/compile them
2) When I'm done, I use "Undefine Function", which then undefines the function from the running Lisp.
That's the key; if you delete a function make sure to undefine it so it's not sticking around in the image.
In slime you can use `C-c C-u` which is bound to FMAKUNBOUND.
this used to be the normal way of programming in lisp repls (like in 01980) but maybe this is good enough
* (defun tri (n) (loop for i from 1 to n summing n))
TRI
* (describe 'tri)
COMMON-LISP-USER::TRI
[symbol]
TRI names a compiled function:
Lambda-list: (N)
Derived type: (FUNCTION (T) (VALUES NUMBER &OPTIONAL))
Source form:
(LAMBDA (N)
(BLOCK TRI
(LOOP FOR I FROM 1 TO N
SUMMING N)))
> When I go to load my code back in, I get errors, because oops I was actually still calling that deleted function somewhere -- it "worked" before because the old function was still hanging out in the image.so a thing you can do in that case is to delete it from the image at the same time
well, you can't really delete it from the image, but you can remove the function binding of the symbol, and since normally in common lisp implementations function calls indirect through the symbol (which is why you can replace the definition with a newer one) deleting the function binding is enough
* (defun tri0 (n) (tri (1+ n)))
TRI0
* (tri0 4)
25
* (tri0 5)
36
* (fmakunbound 'tri)
TRI
* (tri0 5)
debugger invoked on a UNDEFINED-FUNCTION @52A00674 in thread
#<THREAD "main thread" RUNNING {1001348003}>:
The function COMMON-LISP-USER::TRI is undefined.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE ] Retry calling TRI.
1: [USE-VALUE ] Call specified function.
2: [RETURN-VALUE ] Return specified values.
3: [RETURN-NOTHING] Return zero values.
4: [ABORT ] Exit debugger, returning to top level.
("undefined function" 6)
0]
as rainer pointed out, slime has a command for this (i barely use cl myself, you know much more than i do)I also use the REPL for quick tests, and evaluate new code by writing it in emacs and compiling it one function at a time (C-c C-c).
Finally, I keep files of tutorial/demo/test cases which work a bit like a notebook, allowing me to quickly verify that existing 3D scenes still work.
Which is why I do best with the command line, piping outputs and rapidly iterating to get the output I want.
And why I struggled so much writing Python in a larger, more complex script/app. I wanted to constantly run and rerun the smaller parts to get each one just right. Unfortunately that doesn't work great when you're interacting with a half dozen different APIs that take minutes to run each time. Until I realized what was slowing me down, I was just getting more and frustrated.
Now I am at least aware of the issue. Part and parcel of growing from sysadmin to DevOps to coder, I guess? Now I know to look for shims or stubs that help me. Now I can write tests that isolate and verify, rather than run the whole damn thing end to end.
It helps me to think of objects as those command line tools. Their method parameters are the stdin that get passed through pipes. I apologize that this isn't particularly profound, but sometimes epiphanies are made from smaller realizations.
Maybe I should have tried writing part of my most recent script in Lisp? Just to see if it resonated like described in this thread?
> Maybe I should have tried writing part of my most recent script in Lisp?
90% of Lisp programming is selecting an expression in your editor and pressing C-x C-e to execute it. And continue until you are satisfied it operates as you want, then integrate it in the larger system.
One one hand, as you alluded too, I've found unit tests are a great solution to this. Kill two birds with one stone - rapidly iterate on a chunk of code and come out of it with solid test coverage.
It's too bad that's not very feasible in gamedev most of the time with so much going on in the world, but over time I think that environment improved my skills to where it's less of a problem.
admittedly it's hard to save the state of the page after you hack on it in the browser console, but jupyter doesn't really have that problem
Same. That has tripped me so many times when trying out something simple in golang.
I get why they are undesirable in the long run, but in the short run I'm often trying out a fragment and don't have the users of every variable written yet.
When you're exploring, you don't want your compiler to stop you in your tracks to warn you about pedantic nonsense. It's not a syntax error that prevents your compiler from understanding, it's just arbitrary restriction that the compiler decides to pester your about, a sort of a robotic grammar nazi.
Computers are obtuse, the worst thing they can do is ignore your perfectly parseable and valid instructions for arbitrary reasons. Machine, if you know I'm not using a variable, kindly let me know and carry on doing your job.
i don't actually know what he was hacking on at berkeley
You guys want to have your cake and eat it too -- to be correct despite being lazy and sloppy.
It makes no sense. Bite the bullet. Don't have unused variables. There's no such thing as "exploration". After you've "explored" enough (where "explored" means "coded sloppily"), you've quickly exhausted your mental buffer, and it's suddenly expensive to go back and polish what you've done, making yesterday's exploration today's (hopefully not too creaky) foundation.
This is one where faster local development (because you don't have to repeatedly, jarringly stop what you're doing and patch up something that doesn't matter) and clean source in a common repo are both possible and very easy to achieve.
But whatever. Yay go.
If I need to use analysers to fix that, I already have those for C and C++ for the last 30 years.
I think while some of the people he describes may have ADHD, very few people with ADHD are this person. His description resonated with me as a particular archetype, one that often makes their way into grad school eventually. Often enough to be recognizable.
I also don't think the author meant these people are bipolar in a medical sense, but used "bipolar" as the success+failure designation, perhaps unfortunate terminology.
If you're interested in trying to make this work, we can try implementing it first in Python using a shim annotation on every function and making some changes to an existing debugger plugin, it will definitely be difficult to integrate but it should be doable.
For C++, something similar can be done by hacking the compiler to make all functions virtual and then hooking up NativeJIT to recompile functions as-needed. Eventually using something like rr we can even replay execution after we change data structures.
I really resonate with the idea of exploratory programming and find myself in a similar position to you - but I can't use Lisp for most of my work, so given the possibility, I really do think that making tooling that makes this kind of development environment possible is the best option, and I'm pretty sure it's possible to do it, so why not have the best of both worlds?
I also don't see any technical reason you couldn't have the best of both worlds. E.g. a dynamic runtime environment that allows recompiling functions on the fly etc., but also have a separate batch compiler that can type check the program as a whole, do whole program optimizations, etc.
So you can do exploratory programming while developing, and the run the batch compiler before committing changes, when doing releases, etc.
I think the biggest challenge is simply the amount of effort required to design and implement it (and of course someone who's interested enough in it to do it).
Our own self concept is based on the story we tell ourselves. This is an important emotional/intellectual regulatory tool we deal with in a daily basis. Evolution gave us self reflection because it's very useful to us. But it doesn't mean it's a reflection of reality.
The Bipolar Lisp Programmer - https://news.ycombinator.com/item?id=21999802 - Jan 2020 (2 comments)
The Bipolar Lisp Programmer (2007) - https://news.ycombinator.com/item?id=13467473 - Jan 2017 (57 comments)
The Bipolar Lisp Programmer (2007) - https://news.ycombinator.com/item?id=8904208 - Jan 2015 (11 comments)
The Bipolar Lisp Programmer - https://news.ycombinator.com/item?id=8801608 - Dec 2014 (25 comments)
The Bipolar Lisp Programmer (2007) - https://news.ycombinator.com/item?id=3374849 - Dec 2011 (38 comments)
The Bipolar Lisp Programmer - https://news.ycombinator.com/item?id=2275657 - March 2011 (86 comments)
The Bipolar Lisp Programmer (an oldie but a goodie) - https://news.ycombinator.com/item?id=859669 - Oct 2009 (22 comments)
The Bipolar Lisp Programmer - https://news.ycombinator.com/item?id=187867 - May 2008 (15 comments)
The Bipolar Lisp Programmer - https://news.ycombinator.com/item?id=78739 - Nov 2007 (32 comments)
The Bipolar Lisp Programmer - https://news.ycombinator.com/item?id=20012 - May 2007 (8 comments)
(Reposts are fine after a year or so; links to past threads are just to satisfy extra-curious readers)
Every single thing in the article fits my life so far, the boredom, the pointlessness of all things, the ease of brilliance, 1 to 1, sans the sadness because I'm still hopeful that the world can be fixed and am still an idealist. (I attribute this to my faith.)
My classmates always envied how little or none I work for the same results but very few realized it's kind of a curse at the same time[1]. When you don't have a habit of working, you can't work hard when you need it. I think this can be a problem now as I'm entering university (it happened to be a mild problem in late HS too). I would not throw it all up with girls and beer (cos I'm muslim) but I don't know whether I will be bored, because I heard the curriculum isn't exactly full of shiny things.
1: Still I'm forever grateful to Allah for it, no complaints. Learned so much in my all free time not spent doing pointless homework.
Take classes / sit in on lectures from different fields (art history, painting, russian literature, architecture/furniture making... the list goes on, just make sure it's interesting to you). If you've got AP credits racked, your entire first year's worth of requirements just got freed. Use them piece-by-piece over your semesters to explore other avenues rather than graduating a year early. Don't be afraid of 300/400 level classes as a sophomore (assuming you're solid for the first 3 semesters). It's a great way to better integrate with upper classmen while you're still a fledgling.
Join clubs that do different forms of the work you're interested (applications of theory vs problem sets), or entirely different skillsets**. You should be able to meet people above and below you, enabling avenues to learn and teach.
*I never did figure out how deadlines work.
**E.g. sports. "The mind cannot exist without the body" - Morbeus
The failure mode goes "this thing will take two days, I'll start two days before the deadline, oops". The fix is "this thing will take two days, I'll start it immediately". You can then still drop it after two days if you wish, but you have options if your estimate was poor.
my advice is to figure out what you want to get out of it. sure, maybe you need a degree, but that's a really big space. most of it seems like a pointless sysiphysian exercise. but there are some really great teachers and peers in there, and a lifelong passion if you can find it.
If something isn't practical and it doesn't bring you joy then it isn't worth your time. Don't fool yourself into wasting time!
However, I'd strongly disagree with the assertion that lisp is a shallow rabbit-hole. It's probably one of the deepest I've ever been down. There's a good half-century of history there (much of which is even recorded!) - you'll end up learning about four or five different object systems and probably implementing your own, for example - and, even if you want to ignore the past, the accessibility of every level of a lisp system means that I probably know more about how SBCL turns my code into electricity than I ever will about Python, despite never having used the former professionally.
Big big, very deep rabbit-hole filled with a lot of very interesting rabbits.
My career (if may be called that) can be summarized by a constant swing.
On one side, I have a "job" where I start well but after a while I fall out of grace from higher-ups because I inevitably end up calling out their bullshit and/or start seeing the pointlessness of it all and lose interest in progressing there. This leads me to either quitting or getting fired, which brings me to the other side of the swing: I dive into another project where I try to do everything "my way", no compromises, no shortcuts, no justification of "best practices" because "that is how everyone else does it".
While I am on this side, I feel incredibly productive and I am forced to grow/learn a lot of things that are required to the problem at hand. Yet, because of this hard-line stance on not compromising, my projects gets either out-competed by a startup that was (rightly) willing to take the shortcuts I didn't take, or I end up building something that had no market for, or (worse) there is a market and no strong competitor but I refused to pivot out of the original idea for a matter of "principle" that only I cared about - hub20 definitely fell into that category.
When I am finally out of steam (or financial reserves), I go back into the job market, usually with a renewed set of skills which helps me land a job that was better than the previous one, and the cycle is complete.
Honestly, I am tired of this. These swings were fun for the first 3 or 4 times but now I am increasingly feeling that my luck will run out soon and that I need to get out of this swing, no matter on what end. Either I finally make one of my projects more than a nice portfolio piece or I learn how to settle and navigate the corporate world without hating it and myself so much.
Also, I've had little success breaking into any higher-level position as an employee here. For the past 5 years or so I've worked only remotely for foreign companies and/or freelance and/or on my own projects. Employment offers were low-balling me and in a German company who would see me as a simple cog.
Part-time always requires a change in the contract, even as Teilzeit in Elternzeit (at least the part of the contract that says how many hours you need to work has to be changed). All the regulations regarding regular part-time can be found here https://www.gesetze-im-internet.de/tzbfg/index.html §8 is probably the most relevant for you.
It's a nice way to break out of the rat race of bad practices and questionable frameworks being used all over the place and it seems pretty secure because most of the tail-chasing framework types aren't exactly keen to learn the details of what actually takes code from 0 to production-grade so having the breadth of knowledge becomes an asset that lets you work on a variety of problems. Obviously there's a different slew of annoying things to deal with (wrangling cloud services, insane abstraction around infrastructure, etc.) but I think those are more pleasant to work around.
The infra-side of things also hasn't really slowed down in hiring like pure developer positions has.
The fundamental point to keep in mind is that it does not matter. The only thing you are entitled to in a corporation is your salary. Interesting projects and things making sense all over are just side perks. They are very nice perks, I have to say, but they don't pay your rent or put food on your table.
Keep this is mind and life will get easier.
Maybe it's just my (relatively) comfortable upbringing in Brazil or me living for over 10 years in Germany, where I see how the Welfare State affords me some peace of mind in knowing that my kids will be okay even if I give up on my career... but "I just better swallow this bullshit and do so for the majority of my productive life or I won't be able to pay rent" has never been a thought that crossed my mind.
1 he is
2 his time
3 he or
4 his assignments
5 he doesn
6 guy is
7 his low
8 his guitar
9 guy and
10 him go
11 him then
12 he chooses
13 he goes
14 his natural
15 he can
16 he wants
17 he goes
18 he relies
19 his natural
20 him through
21 his assignments
22 He experiences
23 his usual
24 He can
25 his assignment
26 he hands
27 he doesn
28 his official
29 him too
30 his UNIX
31 he would
32 he could
33 his own
34 He flunks
35 He ends
36 He can
37 his strength
38 him to
39 He conceives
40 he embarks
41 his resources
42 his own
43 him so
44 he will
45 his sensitivity
46 he knows
47 he smells
48 He can
49 he is
My conclusion: this is about something that only happens to guys.I like C and assembly because they’re simple from a language semantics level but incidental complexity is nearly unavoidable. I’m not sure if I have undiagnosed ADHD like many here are wondering, but I do wish I could go back to living in a REPL without giving up the joy of working on real hardware at the register programming level.
Perhaps Fennel* fits the bill?
Somehow I've gone 36 years without anyone telling me I could do explorative programming on bare metal, and now I can't shut up about it.
it outputs textual assembly though
Clojure, Nim, Elixir, and more faintly flirt with the true unbridled power of a CL environment, but primarily provide useful abstractions and some familiarity, compatibility, and/or killer features that can't be turned down as easily as a true CL environment. It works out, when the company is small enough that you're driving your own project. Just be sure do document what you did.
You can statically introspect code to then generate related/translated ASTs to create nearly frictionless helper facilities like https://github.com/c-blake/cligen .
You can do all of this without any real run-time speed sacrifices, depending upon the level of effort you put in / your expertise. Since it generates C/C++ or Javascript you get all the abilities of backend compilers almost out of the box, like profile-guided-optimization or for JS JIT compilation.
EDIT: There really is much more, as with any system - I was just trying to give a flavor of what appeals to me.
Other people in this position, what did you do?
edit: I'm also not interested in getting a diagnosis since I don't want it to be on any file in general. Call it paranoia, I don't want some medical file marking me as having a disorder or being mentally ill.
Not paranoia at all, I had a bored psychiatrist showing a wildly unprofessional amount of skin diagnose me with Bipolar type II after a single 15 minute interview, and now I have serious issues getting life insurance. Even with several other psychiatrists giving opposing diagnoses.
Much better to suspect (and apparently trigger some people's disdain) than let someone write something down in permanent ink.
Got medicated, and reduced the amount of billable hours to a minimum that lets me make rent, and gives me a ton of unstructured fun time to pursue today's source of dopamine. Today it's one library, tomorrow it's hacking on a project, next week, who knows?
In other words, make it so programming is a way to express your creativity, rather than simply your day job.
> Got medicated
Used to be addicted to amphetamines so I think I'll pass on this one. It's effective, definitely, but I don't think I can have a sizeable amount of them at disposal or bad things happen.
The alternative to get a ton of dopamine is plenty of exercise, clean diet, protein, good sleep and a generous amount of caffeine. I mean, that's good advice for pretty much everybody.
Given how he defined the term, I suspect he is using the word bipolar in its general meaning of having two states.
Bipolar is a bit of a misnomer as is, multi-polar is a better descriptive what what the disorder actually is. There are not two states, there are several overlapping, non-exclusive “states”. (For example: mania and depression are not exclusive.)
Interestingly enough, I also had a favorite professor in college who mentored and looked out for me to a certain extent, who was big into Lisp and Haskell, and who was quite acquainted with bipolar disorder himself due to other people in his life.
I used Common Lisp for a few years and then switched to Clojure for another four years. At the time, it seemed that Clojure’s ecosystem could overcome the lone-wolf problems that CL faced. In the end, Rich Hickey made it clear that Clojure was his toy that we were lucky to use, and so its ecosystem never took off like it could have. It’s a real pity and a terrible lost opportunity.
Since then I’ve gone all in on languages that I don’t particularly like, but whose ecosystems provide such value that the language itself is somewhat immaterial: JavaScript and Python.
But I do think about lone-wolfing sometimes, in the context of building new products for myself,
If I ever went down that path again, I’d choose Common Lisp over Clojure. Clojure is easier to use, has more libraries, and has JVM interop, but these benefits are outweighed by Clojure’s opinionated restrictions on the language itself. Ultimately, if I am going lone-wolf or nearly-lone-wolf, I might as well use the most powerful language that doesn’t force its opinions on me.
Of course, my life story is such that I've used Python professionally to the extent that I've started to forget all other languages -- so I naturally find the Blub Paradox Discourse favorable. But all the footguns that come with passing around pointers to memory addresses also come with a whole different way of expressing problems; whole different range of thoughts that are thinkable.
(I valiantly await the Rust brigade in my replies...)
On that other side, the positive side, is there a self?
>Another feature about this guy is his low threshold of boredom. He'll pick up on a task and work frantically at it, accomplishing wonders in a short time and then get bored and drop it before its properly finished.
Working frantically at a task doesn't sound like self-realization.
* To a place where other people see the value and join into the project before we burn out.
* To a place where a discovery or insight is made that is valuable without needing to be thoroughly polished. IMHO this is why so many brilliant mathemeticians are bipolar: once an insight is reached and communicated, value has been created. No debugging or security updates required :)
Why would one use Shen over Common Lisp, Racket, Chez Scheme, or Clojure, for example?
The crazy thing about Shen is that its type system is sequent calculus, which means when you define your types, you are literally writing the same language that mathematicians use when they prove things about type theories.
Why would you use it? Because you can leverage a crazy amount of power by writing your own type theories in your programs.
Is it practical in today's corporate world? Probably not, but there is at least one case study in the real world https://www.youtube.com/watch?v=lMcRBdSdO_U
If I am interesting in using functional languages (currently F#, Elixir, and Racket) to explore GUI systems, graphics, symbolic math, numerical computing like machine learning and swarm algorithms and automatic differentiation, agent-based modeling, fractals and general chaos theory stuff, etc., is Shen a good match for that type of exploratory, almost from first principles but towards something that is actually usable work?
Is Shen closer to Scheme or Lisp? I typically fall in the Scheme side of things a la Racket.
Thanks for all the information and help!
It’s closer to scheme I think, being a lisp-1, even though it’s originally implemented in Common Lisp.
This is interesting for sharing code across multi-language projects, e.g. as a JavaScript library and a Java one, where the shen interpreter gets written once per language and now all your library code is callable from any of them.
I think it's a minor misfire that this is an interpreter, as opposed to a compiler from shen to whatever language, but that would be fixable. I'd rather compile the shared definitions to raw c++ code ahead of time than run an interpreter.
Aside from that, the definition is mostly in shen (modulo said primitives) so it has an axiomatic angle to it, and the type checker is a prolog. Compiler and prolog engine both available to user code of course.
I took it to be the ceiling of the dome of Hagia Sofia but I could be wrong. It definitely looks Moorish, though. A grand mosque dome of some kind.
Not saying programmatic decoration would be a bad thing -- it wouldn't! But beware: much Islamic decoration is text. It's writing. You can't just programmatically generate that.
Okay, "AI" chat bots can, but the _text_ is simple. It's the calligraphy that matters. Generating that would be very hard.
This speaks to me. As I get older, I am tempted to start curating a list of my "failed" (or abandoned) projects.
I have been fortunate enough to launch an open-source 3D graphics Lisp project late in life which has managed to keep my interest. Early on, I made a number of conscious decisions about how I would view this project and avoid some mistakes of my past.
- No comparing to existing 3D packages. It's evident that I can't compete with commercial packages with decades of programmer effort.
- No hunting for a "better" language (though this hasn't really been a problem). A goal of the project is to develop a system where I can bring the power of Common Lisp to bear on 3D graphics. In some ways this is a throwback of work I did developing 3D graphics on Symbolics Lisp Machines back at the MIT Media Lab [0]. Returning to my youth?
- Keep it simple. Or, does it need to be more complicated? Understandable code is a benefit, as is code you can (mostly) keep in your head. Avoid excessively clever code, which I have been guilty of in the past (macros, anyone?). Also (more controversially) avoid dependencies where possible; keep it in house.
- Build a community. Having others involved is the best way I have found for not running out of steam. My other projects have invariably been solo efforts. Now I am interested in creating something which will outlast me. Hence the decision to put the project on Github [1].
- This "thing" has value in and of itself, and doesn't need to be "better" than what is out there. By virtue of being different enough, it is a worthwhile project to bring into existence. The world probably doesn't need another browser-based JavaScript package.
- Keep the momentum going by working on whatever interests me at the time. Avoiding tedious development and yak shaving keeps me from losing motivation. I do realize the article touches on this as a weakness of the Lisp developer mindset, and I admit to not being motivated to build an industrial-strength system. E.g. my half-baked GUI built on top of raw OpenGL.
- Finally (have to stop sometime), don't overthink things. Enjoy the journey. I am enjoying enhancing the system while not fretting over who will use it or for what purpose. The journey is the destination.
[0] https://medium.com/@kaveh808/late-night-lisp-machine-hacking...
But I never had problems with the programming assignments or the labs, I enjoyed those. And when I finally got my degree, I found out that all it takes to make hundreds of thousands of dollars is to solve a couple of algorithms for someone. I guess it all worked out in the end, although I do hate the corporate world (and have trouble staying anywhere long) with a passion and would very much like to find a way out.
Note: I was put on bipolar medication because of the wild swings in my grades during college, but I don't believe I am actually bipolar so I no longer take it.
maybe we should work together