- 200 Posts
- 415 Comments
Thanks! I’m currently using DozeCal (which defaults to base 12 on every launch, which is fun, but not usually what I want), and 48sx, which is cool but I don’t know how to use it well, and some common actions are buried.
What font is used in the “DEMAND A NEW NORMAL” banner?
I don’t know how they picked the name for this new terminal, maybe it’s a reference.
It is very good, and I am currently using it. I don’t like its dependencies on GTK stuff, the developer is a little picky about what to support, and I dislike the
+optionsstyle. Other than that, 👍 .Also great: Wezterm, Konsole, Rio. I’m excitedly following Rio’s development, which has a much smaller dependency list, and hopping back and forth between it and Ghostty/Wezterm. But it’s still got some things to iron out and features to develop.
AndyOPMto
Concatenative Programming•Pipelining might be my favorite programming language featureEnglish
1·7 months agoA bigger discussion on Hacker News: https://news.ycombinator.com/item?id=43751076
AndyOPMto
Concatenative Programming•Pipelining might be my favorite programming language featureEnglish
1·7 months agoDiscussion on lobsters too: https://lobste.rs/s/ydxus1/pipelining_might_be_my_favorite
AndyOPMto
Concatenative Programming•lfnoise/sapf: Sound As Pure Form - a Forth-like language for audio synthesis using lazy lists and APL-like auto-mappingEnglish
1·9 months agoA bit from the readme appreciating concatenative programming:
The Joy language introduced concatenative functional programming. This generally means a stack based virtual machine, and a program consisting of words which are functions taking an input stack and returning an output stack. The natural syntax that results is postfix. Over a very long time I have come to feel that syntax gets in between me and the power in a language. Postfix is the least syntax possible.
There are several reasons I like the concatenative style of programming:
-
Function composition is concatenation.
-
Pipelining values through functions to get new values is the most natural idiom.
-
Functions are applied from left to right instead of inside out.
-
Support for multiple return values comes for free.
-
No need for operator precedence.
-
Fewer delimiters are required:
- Parentheses are not needed to control operator precedence.
- Semicolons are not needed to separate statements.
- Commas are not needed to separate arguments.
(Note: Sapf is inspired by, but is not purely a concatenative language because it has lexical variables.)
When I am programming interactively, I most often find myself in the situation where I have a value and I want to transform it to something else. The thing to do is apply a function with some parameters. With concatenative programming this is very natural. You string along several words and get a new value.
-
Andyto
Linux@lemmy.ml•[solved] Any multiline zsh compatible shells? [zsh config]English
1·10 months agoIt’s been a while, but my clumsy adding of a comment to the buffer is unnecessary, given
zle -M, which will display a message outside of the buffer. So here’s an updated version:# -- Run input if single line, otherwise insert newline -- # Key: enter # Credit: https://programming.dev/comment/2479198 .zle_accept-except-multiline () { if [[ $BUFFER != *$'\n'* ]] { zle .accept-line return } else { zle .self-insert-unmeta zle -M 'Use alt+enter to submit this multiline input' } } zle -N .zle_accept-except-multiline bindkey '^M' .zle_accept-except-multiline # Enter # -- Run input if multiline, otherwise insert newline -- # Key: alt+enter # Credit: https://programming.dev/comment/2479198 .zle_accept-only-multiline () { if [[ $BUFFER == *$'\n'* ]] { zle .accept-line } else { zle .self-insert-unmeta } } zle -N .zle_accept-only-multiline bindkey '^[^M' .zle_accept-only-multiline # Enter
The given Uiua example (mercifully given using words rather than the symbols):
[3 4 5 10 23] divide length on /+For all the talk about “forward” it’s uncomfortable to me how the Uiua evaluation within a line happens backward.
An equivalent in Factor, where
keepis close toon:{ 3 4 5 10 23 } [ sum ] keep length /But this pattern of doing two things in sequence to the same item is common enough that
biis handy:{ 3 4 5 10 23 } [ sum ] [ length ] bi /
Day 6
spoiler
: get-input ( -- rows ) "vocab:aoc-2024/06/input.txt" utf8 file-lines ; : all-locations ( rows -- pairs ) dimension <coordinate-matrix> concat ; : guard-location ( rows -- pair ) [ all-locations ] keep '[ _ matrix-nth "<>^v" in? ] find nip ; TUPLE: state location char ; C: <state> state : guard-state ( rows -- state ) [ guard-location ] [ dupd matrix-nth ] bi <state> ; : faced-location ( state -- pair ) [ char>> H{ { CHAR: > { 0 1 } } { CHAR: v { 1 0 } } { CHAR: < { 0 -1 } } { CHAR: ^ { -1 0 } } } at ] [ location>> ] bi v+ ; : off-grid? ( rows location -- ? ) [ dimension ] dip [ v<= vany? ] keep { 0 0 } v< vany? or ; : turn ( state -- state' ) [ location>> ] [ char>> ] bi H{ { CHAR: > CHAR: v } { CHAR: v CHAR: < } { CHAR: < CHAR: ^ } { CHAR: ^ CHAR: > } } at <state> ; : obstacle? ( rows location -- ? ) swap matrix-nth CHAR: # = ; : guard-step ( rows state -- state' ) swap over faced-location { { [ 2dup off-grid? ] [ 2nip f <state> ] } { [ [ obstacle? ] keep-under ] [ drop turn ] } [ swap char>> <state> ] } cond ; : walk-out ( rows state -- trail ) [ [ 2dup location>> off-grid? ] [ dup location>> , dupd guard-step ] until ] { } make 2nip ; : part1 ( -- n ) get-input dup guard-state walk-out cardinality ; : (walk-loops?) ( visited rows state -- looped? ) dupd guard-step 2dup location>> off-grid? [ 3drop f ] [ pick dupd in? [ 3drop t ] [ pick dupd adjoin (walk-loops?) ] if ] if ; : walk-loops? ( rows -- looped? ) dup guard-state [ HS{ } clone ] 2dip pick dupd adjoin (walk-loops?) ; : obstacle-candidates ( rows -- pairs ) [ guard-location ] [ dup guard-state walk-out members ] bi remove ; : part2 ( -- n ) get-input dup obstacle-candidates [ CHAR: # spin deep-clone [ matrix-set-nth ] keep walk-loops? ] with count ;
Slow and dumb gets it done! I may revisit this when I give up on future days.
Factor
spoiler
TUPLE: equation value numbers ; C: <equation> equation : get-input ( -- equations ) "vocab:aoc-2024/07/input.txt" utf8 file-lines [ split-words unclip but-last string>number swap [ string>number ] map <equation> ] map ; : possible-quotations ( funcs numbers -- quots ) dup length 1 - swapd all-selections [ unclip swap ] dip [ zip concat ] with map swap '[ _ prefix >quotation ] map ; : possibly-true? ( funcs equation -- ? ) [ numbers>> possible-quotations ] [ value>> ] bi '[ call( -- n ) _ = ] any? ; : solve ( funcs -- n ) get-input [ possibly-true? ] with filter [ value>> ] map-sum ; : part1 ( -- n ) { + * } solve ; : _|| ( m n -- mn ) [ number>string ] bi@ append string>number ; : part2 ( -- n ) { + * _|| } solve ;
Nothing smart to see here. I may revisit this when I give up on future days.
Factor
spoiler
: get-input ( -- rows ) "vocab:aoc-2024/06/input.txt" utf8 file-lines ; : all-locations ( rows -- pairs ) dimension <coordinate-matrix> concat ; : guard-location ( rows -- pair ) [ all-locations ] keep '[ _ matrix-nth "<>^v" in? ] find nip ; TUPLE: state location char ; C: <state> state : guard-state ( rows -- state ) [ guard-location ] [ dupd matrix-nth ] bi <state> ; : faced-location ( state -- pair ) [ char>> H{ { CHAR: > { 0 1 } } { CHAR: v { 1 0 } } { CHAR: < { 0 -1 } } { CHAR: ^ { -1 0 } } } at ] [ location>> ] bi v+ ; : off-grid? ( rows location -- ? ) [ dimension ] dip [ v<= vany? ] keep { 0 0 } v< vany? or ; : turn ( state -- state' ) [ location>> ] [ char>> ] bi H{ { CHAR: > CHAR: v } { CHAR: v CHAR: < } { CHAR: < CHAR: ^ } { CHAR: ^ CHAR: > } } at <state> ; : obstacle? ( rows location -- ? ) swap matrix-nth CHAR: # = ; : guard-step ( rows state -- state' ) swap over faced-location { { [ 2dup off-grid? ] [ 2nip f <state> ] } { [ [ obstacle? ] keep-under ] [ drop turn ] } [ swap char>> <state> ] } cond ; : walk-out ( rows state -- trail ) [ [ 2dup location>> off-grid? ] [ dup location>> , dupd guard-step ] until ] { } make 2nip ; : part1 ( -- n ) get-input dup guard-state walk-out cardinality ; : (walk-loops?) ( visited rows state -- looped? ) dupd guard-step 2dup location>> off-grid? [ 3drop f ] [ pick dupd in? [ 3drop t ] [ pick dupd adjoin (walk-loops?) ] if ] if ; : walk-loops? ( rows -- looped? ) dup guard-state [ HS{ } clone ] 2dip pick dupd adjoin (walk-loops?) ; : obstacle-candidates ( rows -- pairs ) [ guard-location ] [ dup guard-state walk-out members ] bi remove ; : part2 ( -- n ) get-input dup obstacle-candidates [ CHAR: # spin deep-clone [ matrix-set-nth ] keep walk-loops? ] with count ;
Day 5
spoiler
: get-input ( -- rules updates ) "vocab:aoc-2024/05/input.txt" utf8 file-lines { "" } split1 "|" "," [ '[ [ _ split ] map ] ] bi@ bi* ; : relevant-rules ( rules update -- rules' ) '[ [ _ in? ] all? ] filter ; : compliant? ( rules update -- ? ) [ relevant-rules ] keep-under [ [ index* ] with map first2 < ] with all? ; : middle-number ( update -- n ) dup length 2 /i nth-of string>number ; : part1 ( -- n ) get-input [ compliant? ] with [ middle-number ] filter-map sum ; : compare-pages ( rules page1 page2 -- <=> ) [ 2array relevant-rules ] keep-under [ drop +eq+ ] [ first index zero? +gt+ +lt+ ? ] if-empty ; : correct-update ( rules update -- update' ) [ swapd compare-pages ] with sort-with ; : part2 ( -- n ) get-input dupd [ compliant? ] with reject [ correct-update middle-number ] with map-sum ;
Factor
: get-input ( -- rules updates ) "vocab:aoc-2024/05/input.txt" utf8 file-lines { "" } split1 "|" "," [ '[ [ _ split ] map ] ] bi@ bi* ; : relevant-rules ( rules update -- rules' ) '[ [ _ in? ] all? ] filter ; : compliant? ( rules update -- ? ) [ relevant-rules ] keep-under [ [ index* ] with map first2 < ] with all? ; : middle-number ( update -- n ) dup length 2 /i nth-of string>number ; : part1 ( -- n ) get-input [ compliant? ] with [ middle-number ] filter-map sum ; : compare-pages ( rules page1 page2 -- <=> ) [ 2array relevant-rules ] keep-under [ drop +eq+ ] [ first index zero? +gt+ +lt+ ? ] if-empty ; : correct-update ( rules update -- update' ) [ swapd compare-pages ] with sort-with ; : part2 ( -- n ) get-input dupd [ compliant? ] with reject [ correct-update middle-number ] with map-sum ;
Factor
spoiler
: get-input ( -- rows ) "vocab:aoc-2024/04/input.txt" utf8 file-lines ; : verticals ( rows -- lines ) [ dimension last [0..b) ] keep cols ; : slash-origins ( rows -- coords ) dimension [ first [0..b) [ 0 2array ] map ] [ first2 [ 1 - ] [ 1 (a..b] ] bi* [ 2array ] with map ] bi append ; : backslash-origins ( rows -- coords ) dimension first2 [ [0..b) [ 0 2array ] map ] [ 1 (a..b] [ 0 swap 2array ] map ] bi* append ; : slash ( rows origin -- line ) first2 [ 0 [a..b] ] [ pick dimension last [a..b) ] bi* zip swap matrix-nths ; : backslash ( rows origin -- line ) [ dup dimension ] dip first2 [ over first [a..b) ] [ pick last [a..b) ] bi* zip nip swap matrix-nths ; : slashes ( rows -- lines ) dup slash-origins [ slash ] with map ; : backslashes ( rows -- lines ) dup backslash-origins [ backslash ] with map ; : word-count ( line word -- n ) dupd [ reverse ] dip '[ _ subseq-indices length ] bi@ + ; : part1 ( -- n ) get-input { [ ] [ verticals ] [ slashes ] [ backslashes ] } cleave-array concat [ "XMAS" word-count ] map-sum ; : origin-adistances ( rows origins line-quot: ( rows origin -- line ) -- origin-adistances-assoc ) with zip-with "MAS" "SAM" [ '[ [ _ subseq-indices ] map-values ] ] bi@ bi append harvest-values [ [ 1 + ] map ] map-values ; inline : a-coords ( origin-adistances coord-quot: ( adistance -- row-delta col-delta ) -- coords ) '[ first2 [ @ 2array v+ ] with map ] map-concat ; inline : slash-a-coords ( rows -- coords ) dup slash-origins [ slash ] origin-adistances [ [ 0 swap - ] keep ] a-coords ; : backslash-a-coords ( rows -- coords ) dup backslash-origins [ backslash ] origin-adistances [ dup ] a-coords ; : part2 ( -- n ) get-input [ slash-a-coords ] [ backslash-a-coords ] bi intersect length ;Better viewed on GitHub.
Day 4
spoiler
: get-input ( -- rows ) "vocab:aoc-2024/04/input.txt" utf8 file-lines ; : verticals ( rows -- lines ) [ dimension last [0..b) ] keep cols ; : slash-origins ( rows -- coords ) dimension [ first [0..b) [ 0 2array ] map ] [ first2 [ 1 - ] [ 1 (a..b] ] bi* [ 2array ] with map ] bi append ; : backslash-origins ( rows -- coords ) dimension first2 [ [0..b) [ 0 2array ] map ] [ 1 (a..b] [ 0 swap 2array ] map ] bi* append ; : slash ( rows origin -- line ) first2 [ 0 [a..b] ] [ pick dimension last [a..b) ] bi* zip swap matrix-nths ; : backslash ( rows origin -- line ) [ dup dimension ] dip first2 [ over first [a..b) ] [ pick last [a..b) ] bi* zip nip swap matrix-nths ; : slashes ( rows -- lines ) dup slash-origins [ slash ] with map ; : backslashes ( rows -- lines ) dup backslash-origins [ backslash ] with map ; : word-count ( line word -- n ) dupd [ reverse ] dip '[ _ subseq-indices length ] bi@ + ; : part1 ( -- n ) get-input { [ ] [ verticals ] [ slashes ] [ backslashes ] } cleave-array concat [ "XMAS" word-count ] map-sum ; : origin-adistances ( rows origins line-quot: ( rows origin -- line ) -- origin-adistances-assoc ) with zip-with "MAS" "SAM" [ '[ [ _ subseq-indices ] map-values ] ] bi@ bi append harvest-values [ [ 1 + ] map ] map-values ; inline : a-coords ( origin-adistances coord-quot: ( adistance -- row-delta col-delta ) -- coords ) '[ first2 [ @ 2array v+ ] with map ] map-concat ; inline : slash-a-coords ( rows -- coords ) dup slash-origins [ slash ] origin-adistances [ [ 0 swap - ] keep ] a-coords ; : backslash-a-coords ( rows -- coords ) dup backslash-origins [ backslash ] origin-adistances [ dup ] a-coords ; : part2 ( -- n ) get-input [ slash-a-coords ] [ backslash-a-coords ] bi intersect length ;Better viewed on GitHub
More Factor solutions for the first 3 days (at time of comment) from okflo, on sourcehut.









It’s not my system – I suggest posting in the reddit thread to reach the author.