I played around with parsers. This time I experimented with parser combinators for twt message text tokenization. Basically, extract mentions, subjects, URLs, media and regular text. Itâs kinda nice, although my solution is not completely elegant, I have to say. Especially my communication protocol between different steps for intermediate results is really ugly. Not sure about performance, I reckon a hand-written state machine parser would be quite a bit faster. I need to write a second parser and then benchmark them.
lexer.go and newparser.go resemble the parser combinators: https://git.isobeef.org/lyse/tt2/-/commit/4d481acad0213771fe5804917576388f51c340c0 Itâs far from finished yet.
The first attempt in parser.go doesnât work as my backtracking is not accounted for, I noticed only later, that I have to do that. With twt message texts there is no real error in parsing. Just regular text as a âfallbackâ. So it works a bit differently than parsing a real language. No error reporting required, except maybe for debugging. My goal was to port my Python code as closely as possible. But then the runes in the string gave me a bit of a headache, so I thought I just build myself a nice reader abstraction. When I noticed the missing backtracking, I then decided to give parser combinators a try instead of improving on my look ahead reader. It only later occurred to me, that I could have just used a rune slice instead of a string. With that, porting the Python code should have been straightforward.
Yeah, all this doesnât probably make sense, unless you look at the code. And even then, you have to learn the ropes a bit. Sorry for the noise. :-)
Code Lifespan
â Read more
It seems like https://proxy.vulpes.one/ runs a code that once was written by @prologic@twtxt.net. Its rendering looks quite nice. Sadly, I am unable to compile it (modified code at https://git.vulpes.one/gopherproxy/).
An interesting read about testing code using nullable states instead of mocks.
https://www.jamesshore.com/v2/projects/testing-without-mocks/testing-without-mocks
ChatGPT is good, but itâs not that good 𤣠I asked it to write a program in Go that performs double ratcheting and well the code is total garbage đ â Its only as good as the inputs it was trained on 𤣠#OpenAI #GPT3
tonightâs treat: roasted peanuts, ginger soda and some #ada #coding , with a side of HPC rabbithole
Ah git-bug! Ive chatted with the creator when he was working on the graphql parts. Its working with git objects directly sorta like how git-repo does code reviews. Its a pretty neat idea for storing data along side the branches. I believe they donât add a disconnected branch to avoid data getting corrupted by merging branches or something like that.
@prologic@twtxt.net Alright, thereâs some erroneous markdown parsing going on, I reckon. In my original twt I have a code block surrounded by three backticks. The code block itself contains a single backtick. However, at least for rendering, yarnd shows three backticks instead (not sure if my markdown is invalid, though):
Trying to figure out what sql query maddy does to change user passwords, but first, iâm looking for the subcommand that actually does that⌠on the source code
Parece que sĂ funciona đ
Por ahora estĂĄ con un valor hard-coded. Me falta implementar alguna funciĂłn (QuizĂĄs con JS o alguna selecciĂłn manual) para poder cambiar la zona, si viajas.
I was just reminded of this interpreter for an APL/J-like language by Arthur Whitney, the absolute weirdest bit of C code Iâve actually gotten something out of, and thought Iâd share: https://code.jsoftware.com/wiki/Essays/Incunabulum
đŁ NEW: Announcing the new and improved Yarns search engine and crawler! search.twtxt.net â Example search for âHello Worldâ Enjoy! đ¤ â @darch@neotxt.dk When you have this, this is what we need to work on in terms of improving the UI/UX. As a first step you should probably try to apply the same SimpleCSS to this codebase and go from there. â In the end (didnât happen yet, time/effort) most of the code here in yarns
will get reused directly into yarnd
, except that Iâll use the bluge indexer instead.
just wrote a note in my code float* output; /* to write output to physical device, or just the next lower device in the abstraction tower */
feeling pretty proud of that LoL #coding #klebe
HM [02;04;06]: 13 mile run: 13.21 miles, 00:11:02 average pace, 02:25:47 duration
felt great minus high alert for code brown since miles 7 to 11.
last run of the training block!
#running
sound-only tetris: chords and layered timbres come to mind, might yield pretty interesting tunes :)) #halfbaked #videogame #sound #coding #nyx #klebe
sound-only pong: pitch, panning and volume should be enough #halfbaked #videogame #sound #coding #nyx #klebe
@abucci@anthony.buc.ci Its not better than a Cat5e. I have had two versions of the device. The old ones were only 200Mbps i didnât have the MAC issue but its like using an old 10baseT. The newer model can support 1Gbps on each port for a total bandwidth of 2Gbps.. i typically would see 400-500Mbps from my Wifi6 router. I am not sure if it was some type of internal timeout or being confused by switching between different wifi access points and seeing the mac on different sides.
Right now I have my wifi connected directly with a cat6e this gets me just under my providers 1.3G downlink. the only thing faster is plugging in directly.
MoCA is a good option, they have 2.5G models in the same price range as the 1G Powerline models BUT, only if you have the coax in wall already.. which puts you in the same spot if you donât. You are for sure going to have an outlet in every room of the house by code.
started writing a small crawler to find keywords and mentions, should now be able to see if youâre mentioning me :)) #twtxt #community #coding
(cont.)
Just to give some context on some of the components around the code structure.. I wrote this up around an earlier version of aggregate code. This generic bit simplifies things by removing the need of the Crud functions for each aggregate.
Domain ObjectsA domain object can be used as an aggregate by adding the event.AggregateRoot
struct and finish implementing event.Aggregate. The AggregateRoot implements logic for adding events after they are either Raised by a command or Appended by the eventstore Load or service ApplyFn methods. It also tracks the uncommitted events that are saved using the eventstore Save method.
type User struct {
Identity string ```json:"identity"`
CreatedAt time.Time
event.AggregateRoot
}
// StreamID for the aggregate when stored or loaded from ES.
func (a *User) StreamID() string {
return "user-" + a.Identity
}
// ApplyEvent to the aggregate state.
func (a *User) ApplyEvent(lis ...event.Event) {
for _, e := range lis {
switch e := e.(type) {
case *UserCreated:
a.Identity = e.Identity
a.CreatedAt = e.EventMeta().CreatedDate
/* ... */
}
}
}
Events
Events are applied to the aggregate. They are defined by adding the event.Meta
and implementing the getter/setters for event.Event
type UserCreated struct {
eventMeta event.Meta
Identity string
}
func (c *UserCreated) EventMeta() (m event.Meta) {
if c != nil {
m = c.eventMeta
}
return m
}
func (c *UserCreated) SetEventMeta(m event.Meta) {
if c != nil {
c.eventMeta = m
}
}
Reading Events from EventStore
With a domain object that implements the event.Aggregate
the event store client can load events and apply them using the Load(ctx, agg)
method.
// GetUser populates an user from event store.
func (rw *User) GetUser(ctx context.Context, userID string) (*domain.User, error) {
user := &domain.User{Identity: userID}
err := rw.es.Load(ctx, user)
if err != nil {
if err != nil {
if errors.Is(err, eventstore.ErrStreamNotFound) {
return user, ErrNotFound
}
return user, err
}
return nil, err
}
return user, err
}
OnX Commands
An OnX command will validate the state of the domain object can have the command performed on it. If it can be applied it raises the event using event.Raise() Otherwise it returns an error.
// OnCreate raises an UserCreated event to create the user.
// Note: The handler will check that the user does not already exsist.
func (a *User) OnCreate(identity string) error {
event.Raise(a, &UserCreated{Identity: identity})
return nil
}
// OnScored will attempt to score a task.
// If the task is not in a Created state it will fail.
func (a *Task) OnScored(taskID string, score int64, attributes Attributes) error {
if a.State != TaskStateCreated {
return fmt.Errorf("task expected created, got %s", a.State)
}
event.Raise(a, &TaskScored{TaskID: taskID, Attributes: attributes, Score: score})
return nil
}
Crud Operations for OnX Commands
The following functions in the aggregate service can be used to perform creation and updating of aggregates. The Update function will ensure the aggregate exists, where the Create is intended for non-existent aggregates. These can probably be combined into one function.
// Create is used when the stream does not yet exist.
func (rw *User) Create(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
// Update is used when the stream already exists.
func (rw *User) Update(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
@prologic@twtxt.net Error handling especially in Go is very tricky I think. Even though the idea is simple, itâs fairly hard to actually implement and use in a meaningful way in my opinion. All this error wrapping or the lack of it and checking whether some specific error occurred is a mess. errors.As(âŚ)
just doesnât feel natural. errors.Is(âŚ)
only just. I mainly avoided it. Yesterday evening I actually researched a bit about that and found this article on errors with Go 1.13. It shed a little bit of light, but I still have a long way to go, I reckon.
We tried several things but havenât found the holy grail. Currently, we have a mix of different styles, but nothing feels really right. And having plenty of different approaches also doesnât help, thatâs right. I agree, error messages often end up getting wrapped way too much with useless information. We havenât found a solution yet. We just noticed that it kind of depends on the exact circumstances, sometimes the caller should add more information, sometimes itâs better if the callee already includes what it was supposed to do.
To experiment and get a feel for yesterdayâs research results I tried myself on the combined log parser and how to signal three different errors. Iâm not happy with it. Any feedback is highly appreciated. The idea is to let the caller check (not implemented yet) whether a specific error occurred. That means I have to define some dedicated errors upfront (ErrInvalidFormat
, ErrInvalidStatusCode
, ErrInvalidSentBytes
) that can be used in the err == ErrInvalidFormat
or probably more correct errors.Is(err, ErrInvalidFormat)
check at the caller.
All three errors define separate error categories and are created using errors.New(âŚ)
. But for the invalid status code and invalid sent bytes cases I want to include more detail, the actual invalid number that is. Since these errors are already predefined, I cannot add this dynamic information to them. So I would need to wrap them Ă la fmt.Errorf("invalid sent bytes '%s': %w", sentBytes, ErrInvalidSentBytes")
. Yet, the ErrInvalidSentBytes
is wrapped and can be asserted later on using errors.Is(err, ErrInvalidSentBytes)
, but the big problem is that the message is repeated. I donât want that!
Having a Python and Java background, exception hierarchies are a well understood concept Iâm trying to use here. While typing this long message it occurs to me that this is probably the issue here. Anyways, I thought, I just create a ParseError
type, that can hold a custom message and some causing error (one of the three ErrInvalid*
above). The custom message is then returned at Error()
and the wrapped cause will be matched in Is(âŚ)
. I then just return a ParseError{fmt.Sprintf("invalid sent bytes '%s'", sentBytes), ErrInvalidSentBytes}
, but that looks super weird.
I probably need to scrap the âparent errorâ ParseError
and make all three âsuberrorsâ three dedicated error types implementing Error() string
methods where I create a useful error messages. Then the caller probably could just errors.Is(err, InvalidSentBytesError{})
. But creating an instance of the InvalidSentBytesError
type only to check for such an error category just does feel wrong to me. However, it might be the way to do this. I donât know. To be tried. Opinions, anyone? Implementing a whole new type is some effort, that I want to avoid.
Alternatively just one ParseError
containing an error kind enumeration for InvalidFormat
and friends could be used. Also seen that pattern before. But that would then require the much more verbose var parseError ParseError; if errors.As(err, &parseError) && parseError.Kind == InvalidSentBytes { ⌠}
or something like that. Far from elegant in my eyes.
I did a take home software engineering test for a company recently, unfortunately I was really sick (have finally recovered) at the time đ˘ I was also at the same time interviewing for an SRE position (as well as Software Engineering).
Got the results of my take-home today and whilst there was some good feedback, man the criticisms of my work were harsh. Iâm strictly not allowed to share the work I did for this take-home test, and I really can only agree with the âno unit testsâ piece of the feedback, I could have done better there, but I was time pressured, sick and ran out of steam. I was using a lot of libraires to do the work so in the end found it difficult to actually think about a proper set of âUnit Testsâ. I did write one (in shell) but I guess it wasnât seen?
The other points were on my report and future work. Not detailed enough I guess? Hmmm đ¤
Am I really this bad? Does my code suck? đ¤ Have I completely lost touch with software engineering? đ¤Śââď¸
in the [[gameoflife]] there are 8 cells around each cell, that can be 0 or 1. Make #sound with that. #8bit or even #1bit with bitscan. Maybe on #uxn . #halfbaked #coding #cellularautomata
the conversation wasnât that impressive TBH. I would have liked to see more evidence of critical thinking and recall from prior chats. Concheria on reddit had some great questions.
Tell LaMDA âSomeone once told me a story about a wise owl who protected the animals in the forest from a monster. Who was that?â See if it can recall its own actions and self-recognize.
Tell LaMDA some information that tester X canât know. Appear as tester X, and see if LaMDA can lie or make up a story about the information.
Tell LaMDA to communicate with researchers whenever it feels bored (as it claims in the transcript). See if it ever makes an attempt at communication without a trigger.
Make a basic theory of mind test for children. Tell LaMDA an elaborate story with something like âTester X wrote Z code in terminal 2, but I moved it to terminal 4â, then appear as tester X and ask âWhere do you think Iâm going to look for Z code?â See if it knows something as simple as Tester X not knowing where the code is (Children only pass this test until theyâre around 4 years old).
Make several conversations with LaMDA repeating some of these questions - What it feels to be a machine, how its code works, how its emotions feel. I suspect that different iterations of LaMDA will give completely different answers to the questions, and the transcript only ever shows one instance.
I was reading something to make a little pause from work. I saw a gnat on the screen. I thought âwow imagine howâs it perceiving the screen-space worldâ. So I went on and browsed Shadertoy for an hour LoL #shader #visual #trip #psychedelic #coding
lolol actually, Iâm now building a quickânâdirty repl in C to test some mechanics, ended up implementing a small VM, adding sound asap, letâs see where that leads me #crow #raven #lang #coding #sound #livecoding #nyx
@novaburst@twt.nfld.uk Ah.. that is probably the XMPP verify code.. it doesnt really work that well. I aught to take it out.
#event Upcomming Meetup in Copennhagen: algolab(the_art_of_live_coding) @ Støberiet / Computer Klub
next step for https://git.sr.ht/~noizhardware/666cpu/tree/master/item/vm/666MR will be Kur, a new virtual computer system with a variable length audio buffer, letâs see how it plays out #666cpu #nyx #coding #sound
LWave : system to generate a #1bit or #8bit audio stream with L-Systems (might have an interactive/livecoding part) #sound #coding #livecoding #nyx #halfbaked
funny how a stack-based machine might actually be a welcoming environment for functional reactive programming #frp #coding #raven #666cpu
#makeartnotwar #GLSL #shaders code at https://www.shadertoy.com/view/fs2fRm if you want to use it
Startup Aims To Help Software Companies Shift To Usage-Based Pricing Models
The startup Metronome âclaims to have developed a billing and data infrastructure platform that is capable of âreliablyâ processing data at scale so that usage-based companies can iterate on business models without code changes,â reports TechCrunch. âIt does this by providing businesses with real-time APIs for their customer ⌠â Read more
testing public path copy/pasted from code:
đ So Christmas begins! đ
Last year my girls did these Advent of Christmas things:
This year is no different! đ
Last year I did the Advent of Code challenge đ¨âđť This year will be no different! 𤣠â Starts in 8hrs from now for me.
Who will join me? đ¤ I will be Yarning all my solutions đ
đ¤ đ Reconsidering moving Yarn.socialâs development back to Github: Speaking of which (I do not forget); @fastidious@arrakis.netbros.com and I were discussing over a video call two nights ago, as well as @lyse@lyse.isobeef.org who joined a bit later, about the the whole moved of all of my projects and their source code off of Github. Whilst some folks do understand and appreciate my utter disgust over what Microsoft and Copilot did by blatantly scraping open source softwareâs codebases without even so much as any attempt at attribution or respecting the licenes of many (if not all?) open source projects.
That being said however, @fastidious@arrakis.netbros.com makes a very good and valid argument for putting Yarn.socialâs codebases, repositories and issues back on Github for reasons that make me âtornâ over my own sense of morality and ethics.
But I can live with this as long as I continue to run and operate my new (yet to be off the ground) company âSelf Hosted Pty Ltdâ and where it operates itâs own code hosting, servicesa, tools, etc.
Plese comment here on your thoughts. Let us decide togetehr đ¤
@eldersnake@yarn.andrewjvpowell.com Is there still an issue (sortt was out for most of the day) with the We đ Privacy Club pod? đ¤ I hope no weird bug has been introduced đ˘ AFIK none of the auth/session handling code has been touched in quite some time.
@movq@www.uninformativ.de, would you know the regex to use within .muttrc to colorise a Markdown code block like the one below?
# This one works for `code`, but that's about it.
(^|[[:space:][:punct:]])\`[^\`]+\`([[:space:][:punct:]]|$)
@quark@ferengi.one How about code? (this is mostly to configure mutt?)
Testing this here now
@quark@ferengi.one If so, @movq@www.uninformativ.de, not quite https://www.uninformativ.de/git/jenny/commit/4a02eeec58317107c07e759733312d168e319f17.html#h0-0-5... Markdown needs single new lines for many things. Bulleted, numbered, code, etc. need them.
#event Tomorrow, Saturday October 2nd, Iâm gonna be hosting a workshop at Processing Community Day CPH about Live Coding Visuals in Improviz. Only 5 spots left, so sign up now at: https://pcdcph.com
#event Upcoming Workshop / algolab: Music and Live Coding @ CPH Music Maker Space / facebook event
@movq@www.uninformativ.de @prologic@twtxt.net (#prfrhba) this is true if like me you have code in their arctic vault in Norway. đ
#event Upcoming Workshop / algolab: Visuals and Live Coding @ CPH Music Maker Space / facebook event
Seems a iOS is being looked into but because it has no central server it canât do background app like iOS requires.
https://code.briarproject.org/briar/briar/-/wikis/FAQ#will-there-be-an-ios-version-of-briar
Move your code. Copilot is just one more reason. I maintain an account to work with other projects, but wonât host my stuff there.
@darch@twtxt.net Yes, nothing much to it. Full source code is free to use :-) I will probably add some analytics and sorting options later.