Markdown needs to stay human readable and "simple." Yes, I like some of the bolt on capabilities but I also want a document format that can be read using the simplest interfaces like text editors and os utilities like cat. That's THE reason it is our standard for documentation. I can make it pretty with a nice renderer but also read it, version it, consume it in a ton of tools (like AI Agents) using simple tools.
My advice: Start your own cybersecurity company. No one will hire you for any IT position. So you need to create your own. A niche that isn't being addressed is cybersecurity offerings targeted to small nonprofits. You'd make a killing.
As a tech person, I am treated like a machine, one that should be in a closet -- not seen or heard, they just want work output and they don't want my opinion about whether what they propose is a good idea or bad one (spoiler, most of them are astoundingly bad since non-tech managers are usually as dumb as a box of rocks). I hate my job and increasingly my whole life. It would be great to work for people who know the value of what you do, and the tremendous effort required to do things right, and to just ask the question asked here (with an obvious interest in a real answer and a compassionate ear to hear it).
I agree with gcatalfamo, while infinite scrolling websites seem like, "hey that's cool, I want to be with the in design crowd" they are actually pretty heinous for all the reasons mentioned above. I want a scroll bar that reflects were I actually stand with info contained on the page, not the content that is currently on that page. Refreshs and navigation don't bring you back to where you were. I just think they are obnoxious. I'd rather page through results and be able to predictably get the results from those operations that I expect. Just say NO to infinite scroll!
Infinite scrolling usually is usually time ordered data. If you could type a link with an arbitrary date and time and it took you to the right place, then that might help slightly and would not be that hard to set up. The problem with infinite scroll is it needs extra elements to make it nice, not that it is evil in and of itself.
This was a great article. I've spent the last year filling in gaps in my own CS background including CL, Scheme, Racket, CISP, HtDP, etc. This is the first time I've seen good solid reasoning about Scheme using Assembly and it makes things really clear. I wish the author would have taken a little more time reasoning to the correctness of recursion using the y combinator. That's what he ended up with but it would have been helpful to break that down a bit more. Also, he mentioned that his next article in that series would have covered continuations (specifically call-with-current-continuation) and I REALLY would have enjoyed that since I find continuations a little hard to grasp.
I noticed the implicit y combinator as well... here's something I wrote in python some time ago to play with the idea:
def tco(fn):
"""
tco
---
Usage:
Functions should have the following form:
>>> recursive_fn = lambda fn: lambda x: fn(x+1) if x < 1000000 else x
or
>>> def recursive_fn(fn):
... def recursive_fn_cc(x):
... return fn(x+1) if x < 1000000 else x
... return recursive_fn_cc
The notable difference is that called on their own, these
functions aren't recursive at all. For example,
>>> recursive_fn(lambda x: x)(1)
2
This is easier to see in the anonymous-style definition:
>>> lambda fn: lambda x: fn(x+1) if condition(x) else x
So we go from
>>> def recur(x):
... ( function body modifying x )
... if not base_case_reached:
... return recur(x)
... else:
... return x
to
>>> @tco
... def recur(fn):
... def _lambda(x):
... ( function body modifying x )
... if not base_case_reached:
... return fn(x)
... else:
... return x
... return _lambda
Then call as usual like
>>> recur(x)
Functions need to take this form as it exposes the fixed-point,
namely the recursive `fn`. We need a fixed-point for the modified
y-combinator. The modified combinator is the same, only where the
evaluation step would normally take place, each evaluation is
suspended or "thunked" by wrapping in a `lambda`. The thunks
are then looped over and called in a while-loop, sidestepping
the recursion depth issue.
TODO: save the kwargs; eliminate the need to write the functions
as continuations (i.e. `recur = lambda fn:lambda x: ...`) by creating
new function objects from bytecode, replacing instances of `LOAD_GLOBAL`
with `LOAD_DEREF`, may need to build temp function in order to create
closure so `fn` can be added in `co_freevars`. See e.g.
http://nbviewer.ipython.org/github/bravegnu/python-byte- code/blob/master/Python%20Byte%20Code%20Hacking.ipynb
"""
# y combinator with evaluation step wrapped in throwaway lambda
# which suspends the evaluation step;
# important to give `_t_c_o_` or some other highly unlikely keyword
# argument so we can signal to the loop when stop evaluating;
# want to be able to *return* a function as well, so checking for
# '__call__' in directory is not enough.
# Could also check that argcount is zero, and no other keywords exist;
# if we're really nuts, generate a uuid or timestamp, then assign
# it to `_t_c_o_`
Y = (lambda f: (lambda x: x(x))(
lambda y: f(lambda *args: lambda _t_c_o_=None: y(y)(*args))))(fn)
def tco_cc(*args):
_fn = Y(*args)
while ('__call__' in dir(_fn)) and ('_t_c_o_' in _fn.__code__.co_varnames):
_fn = _fn()
return _fn
return tco_cc
...re-reading this I realize the comments are a bit of a mess... basically, it's a decorator that uses the y-combinator to get around the recursion depth problem by "suspending" the evaluation at each step (I'm sure there's some technical term for this... thunking?), then later performing each evaluation inside a while loop. I tested it a bunch and it seemed to work on anything.
I recall being convinced keyword arguments could be made to work, and also that some byte code hacking would get around the "non-user friendly" bit where recursive functions need to be written as "functionals" in order to expose the recursive function itself as a fixed point.
It was cobbled together more or less from scratch mainly based on stackoverflow questions and wikipedia articles. To be honest, it was still somewhat opaque to me (hence the extraordinarily long comments--trying to explain it to myself) but the javascript link makes things much clearer! Thanks
reply