Finally finished the art of @JunkRaven , SEKHMET-class NHP, hanging out in her subaltern!
Here she is, chilling out at a bar/Horizon Collective clubhouse out somewhere in the Long Rim, with some of her buddies.
This one took a couple of months to finish. I don't think I've ever tried something this detailed, with so much going on in the background! (I'm bad at drawing environments.)
Layout primarily done in #Blender, poster designs done in #Inkscape, and everything else done in #Krita.
No generative AI was used to create this image.
Iāve been thinking about how my ideal #Lisp would work, and I already know that I want it to have very similar semantics to #Lua. but I figured out some fun details. for example, ideally the only non-primitive data type would be Lua-style tables. which means that S-expressions would be converted by the reader into tables (not linked lists!)
so for example this S-expression:
(+ 1 2 (* 3 4))
would become the equivalent of this Lua code: (with 0-based indexes instead of Luaās 1-based indexes because those are an affront to the machine spirits)
{
[0] = symbol("+"),
[1] = 1,
[2] = 2,
[3] = {
[0] = symbol("*"),
[1] = 3,
[2] = 4,
},
}
but of course a Lua table lets you have more keys than just numbers (it acts as a list and as a dictionary!), so I would have a syntax for that in the Lisp too:
(some-func [:some-arg some-value]
[:another-arg another-value])
{
[0] = symbol("some-func"),
[keyword("some-arg")] = symbol("some-value"),
[keyword("another-arg")] = symbol("another-value"),
}
which means that all functions get keyword arguments by default, with no hacks needed! it also provides a nice Racket-like syntax for certain forms:
(let ([foo some-value]
[bar another-value])
; code goes here
)
and IMO the biggest improvement from regular Lisp is that this language would have a special syntax for getting/setting a value from a table:
foo.bar.baz
; this ā gets turned into this ā by the reader
(. foo 'bar 'baz)
; ā which is the same as this ā
(. (. foo 'bar) 'baz)
; you can also use it with functions like `set!`, `set`, `update!`, `update`, etc.
(define foo '())
(set! foo.bar '())
(set! foo.bar.baz 666)
foo ; -> '([bar ([baz 666])])
foo.bar.baz ; -> 666
(update! foo.bar.baz add1)
foo.bar.baz ; -> 667
of course I would also want to have metatables:
(define some-table '())
(set! (meta some-table)
'([foo bar]))
(meta some-table) ; -> '([foo bar])
and metamethods:
(define some-table '())
(set! (meta some-table)
'([:+
(Ī» (self other) "wait - this isn't doing addition!")]
[:+r
(Ī» (self other) "this isn't addition either!")]))
(+ some-table '()) ; -> "wait - this isn't doing addition!"
(+ '() some-table) ; -> "this isn't addition either!"
there would be a special case where the reader turns #this into a reference to the table that itās currently inside of:
(define some-table '())
(set! (meta some-table)
'([:index #this]
[foo bar]))
(. some-table 'foo) ; -> 'bar
and it would also shamelessly steal āborrowā the absolutely incredible : syntax for calling methods in Lua:
(define some-table
(set (meta '([some-value 0]))
'([inc-some-value
(Ī» (self) (update! self.some-value add1))])))
(define inc-some-value
some-table:inc-some-value)
; this ā is equivalent to this ā (it automatically supplies `self`)
(define inc-some-value
(Ī» () (some-table.inc-some-value some-table)))
some-table.some-value ; -> 0
(some-table:inc-some-value)
some-table.some-value ; -> 1
(inc-some-value)
some-table.some-value ; -> 2
oh and importing would just execute the contents of the file youāre importing and then evaluate to the result of the last form! just like itās inside of a (do) form:
; ./some-lib.kaslisp
(define lib '())
(set! lib.foo 12)
; this file now evaluates to the table called `lib`, because that's the last form (just like how a function works!
lib
; ./why-is-this-lib-a-number.kaslisp
; this one just evaluates to 666? that's a weird thing to do...
666
; ./main.kaslisp
(define some-lib (require "./some-lib.kaslisp"))
some-lib ; -> '([foo 12])
some-lib.foo ; -> 12
(require "./why-is-this-lib-a-number.kaslisp") ; -> 666
it just puts all the code inside of a function that takes no arguments, and then runs the function! so importing would have very simple easy-to-understand semantics
Be gay.
Do crimes.
Post about being gay.
DO NOT POST ABOUT DOING CRIMES.
It's quite simple.
Star Trek Resurgence is actively being delisted as the rights have expired. Snag it on PC or any of the consoles while you can. #StarTrek #Gaming #StopKillingGames
Iāve decided that I want to give #Racket another chance, and see if I can work out solutions to the problems that I ran into when trying to use it. itās definitely the #Lisp that feels most practical to me out of everything that Iāve tried, and I still love the contract system and its specific take on threading macros
I remember that the error tracebacks were often missing important info, so I want to wait until that happens and see if I can figure out what the specific problem is/was
I was also trying to get some kind of static function signature checking, to make sure I was calling things right, but Iāve decided that Iām okay with relying on runtime errors (from contract violations) instead, as long as I can read the error tracebacks easily enough
another problem that I ran into while using it is that it feels clumsy and awkward to work with complex data structures
with Python Iām used to being able to nest objects pretty much arbitrarily deep, and have my LSP autocomplete all of the fields/methods at each step so I know exactly what type of data I have, and what I can do with it. with Racket that isnāt really the case - I need to flip through my source code in another split to remember what data I have at each step and how to transform it. I donāt think thereās a solution for this - I think Iāll just have to deal with this unfortunately
another aspect of Racket handling complex data structures clumsily is just that the syntax for drilling into a data structure is pretty noisy and long:
(~> some-data-structure
(get-field foo _)
(hash-ref "some-key")
(list-ref 0)
some-struct$-field)
compare that to most other languages, which would let you just write:
some_data_structure.foo["some-key"][0].field
this problem gets so much worse when you need to actually mutate the data, and even worse than that when itās immutable. hereās a real function that I wrote in Racket: (itās for a really basic clicker game)
(define/contract (game-state$-buy-autoclicker state ac-name)
(-> game-state$? string? game-state$?)
(define-struct-lenses game-state$)
(define-struct-lenses ac-slot$)
(define &ac
(lens-compose (&hash-ref ac-name) &game-state$-autoclickers))
(define ac-cost
(~> (&ac state)
ac-slot$-cost))
(printf "buying autoclicker ~a for cost ~a\n" (&ac state) ac-cost)
(define &ac-num-owned
(lens-compose &ac-slot$-num-owned &ac))
(define new-state
(~> state
(game-state$-clicks-update (-= ac-cost))
(lens-update &ac-num-owned _ (+= 1))))
(if (negative? (game-state$-clicks state))
(error "not enough clicks to buy this autoclicker")
new-state))
pretty much all itās doing is this:
class GameState:
def buy_autoclicker(self, ac_name):
ac = self.autoclickers[ac_name]
cost = ac.get_cost()
print(f"buying autoclicker {ac} for cost {cost}")
if cost > self.clicks:
raise Exception("not enough clicks to buy this autoclicker")
ac.num_owned += 1
self.clicks -= cost
but the combination of nested data and immutability make it a huge mess in Racket
Iām definitely open to suggestions for how I can make this type of code shorter and easier to read, but for the moment hereās what Iām going to try:
Iām going to stop using structs completely in favor of classes, because classes are a great way to have mutability (which fixes the immutability problem) which is neatly contained in a way that can be easily unit-tested, and the syntax and semantics for dealing with classes are often shorter, simpler, and more consistent too
Iām also going to see if I can make a series of general-purpose āget/set/update the data in this nested data structureā forms:
(get-in some-data '(0 3 field-name "some-key"))
; returns some_data[0][3].field_name["some-key"]
(set-in some-data '(0 3 field-name "some-key") "new-value")
; returns a version of some_data with the specific data changed
; etc.:
(set!-in some-data '(0 3 field-name "some-key") "new-value")
(update-in some-data '(0 3 field-name "some-key") (+= 1))
(update!-in some-data '(0 3 field-name "some-key") (+= 1))
that way, my very first example would look like this instead:
(get-in some-data-structure '(foo "some-key" 0 field))
and I could refactor my function into a method that looks like this:
(define (buy-autoclicker ac-name)
(define ac (hash-ref autoclickers ac-name))
(define cost (send ac get-cost))
(printf "buying autoclicker ~a for cost ~a\n" ac cost)
(when (> cost clicks)
(error "not enough clicks to buy this autoclicker"))
(set! clicks (- clicks cost))
(update-field! num-owned ac add1))
thatās dramatically shorter and nicer
hereās a pretty cool video for anyone who likes #NewVegas : this guy travels to a lot of the locations in the game IRL
Traveling The Path of The Courier: A Fallout New Vegas Adventure
apparently someone in Goodsprings calls himself Easy Pete and claims to be the guy that the character was based on, but nobodyās sure if heās playing a role for tourists or if thatās actually true
Somehow it's #PortfolioDay again. Let's do this.
I'm Paul, and I draw illustrations of devils and demigoddesses, elves and other fantasy characters, as my whims take me.
Almost everything I draw is in my post history, or my gallery hosted at https://baffledwizard.blogspot.com/.
I'm generally open to interesting collaborationsāespecially #Illustration, #Gaming or #TTRPG stuff. DM me or email ravanon[at]outlook[dot]com.
#MastoArt #FediArt #ArtistsOnMastodon #Fantasy #CommissionsOpen
explaining why you shouldn't bodyshame even bad people feels like man-ray with patrick's wallet
"you're insulting this person for an unrelated trait"
"yes"
"so you think having that trait is something they should be ashamed of"
"yes"
"so you think that trait itself is shameful"
"no im only making fun of the bad person"
never forget that on the internet you are at risk of being quoted in wiktionary at all times https://en.wiktionary.org/wiki/pakige
Personally I think alt-text is valuable for everyone, not for just people with visual impairments. I read alt-text all the time. I'm curious if my theory that a wide swath of people read alt-text is true.
#AltTxt #AltText
Hey fedi perverts! One of my partners is looking for a "extra soft" fantasy dildo. Their current one broke, and they're struggling to find one, as it seems most places *either* sell extra soft dildos that are human shaped OR fantasy dildos that are medium firmness or above that.
Partner is in Canada, but can order from most places :3
bonus points if it's a small maker (they used to buy them on etsy before etsy's purge)
Now you can play Dwarf Fortress in your MtG games... wut...?
idk if this is a hot take but Resident Evil boss fights suck
I love Resident Evil games but the boss fights are usually:
itās basically just a check to make sure you have as many consumables and healing items as the devs think you do. (for some reason I almost never do?) if not, youāre going to be stuck there until you manage to just barely squeeze by on like your 12th attempt through sheer luck
Iām honestly not sure what a good Resident Evil boss would look like (you might be able to kinda ham-fistedly make it better by adding an iframe-dodge, or making the arena bigger) but what theyāre currently doing is just pure frustration
actually, maybe they could make the boss fights more scripted and horror-y, where the whole thing is designed so that the player will get through it on their first attempt (killing the player in a horror segment is the last thing you want to do. it kills all the fear and tension)
xml is a bad format because itās tedious for people to write and being text-based itās inefficent for computers too. worst of both worlds
that extends to html. with how much of a pain writing html by hand is - it is possible to make a website in notepad, but itās a soulcrushing chore! - i can see where the popularity of web frameworks comes from
so the web platform is overall kind of a disaster and it might be a wheel worth reinventing
Good day folks!
This is probably an odd request, but as the owner and operator of TubeFree.org I want the platform to be as open as possible. But only speaking English I'm VERY limited in reviewing videos.
Does anyone know a translator that could help with persian? Or a tool?
All of the tools I'm finding don't support it and I have someone that uploaded some videos in Persian.
It appears to be a debate or discussion about Iran. I'm absolutely compelled the to leave the video up, but I would love to know the discussion.
ANY help is appreciated. Including if you think you know a friend of a friend or a tool that might work.
Thank you so much!
in theory the Monster Hunter games sound great for me because they have combat similar to the Dark Souls games, except you avoid attacks with positioning instead of precisely-timing your iframes. which is exactly what Iād want (I never liked iframe-based dodging - especially in Soulslikes)
but then I look up Monster Hunter stuff and hear phrases like ātear open the wound to extract bloodā and āat low health it will start limpingā and like no actually Iām good. I donāt want any part of that 
Someone Bought 30 WordPress Plugins and Planted a Backdoor in All of Them.
https://anchor.host/someone-bought-30-wordpress-plugins-and-planted-a-backdoor-in-all-of-them/
#WordPress #WebDev #InfoSec #security #safety #malware #plugin