isaacschemm: A cartoon of myself as a snail (snail8)
[personal profile] isaacschemm

When working in .NET, it can be awkward to figure out whether two objects are "equal". With reference types, two variables might refer to the same object on the heap, or to two different objects with identical properties. In the picture below, changing Snail C's shirt would also change Snail B's, because they are the same snail, while the otherwise identical Snail A is unchanged.

A points to one drawing, B and C both point to another        identical drawing; A is not equal to B, but B is equal to C

Value types are more like C structs. So giving Snail C a jacket and hat does not affect Snail B. It wouldn't make sense to do a "reference comparison" on a value type; the objects are always stored in different places (setting aside explicit pointers to objects in memory, of course - something C# also allows for).

A      and B point to separate but identical drawings, and are equal; C      points to a different drawing, where the snail has a hat, and is      not equal to B

Immutable types with built-in structural equality checks are a great way to work around this issue, but there's still the question of what to do for collection types - the standard .NET HashSet, List and Array types aren't immutable, and even ImmutableList and ImmutableSet don't consider two lists or two sets with the same items to be "equal". But there's a very easy way to handle this problem: you can use the collection types in the F# standard library (FSharp.Core), even without using F#.

Read more... )
isaacschemm: A cartoon of myself as a snail (snail8)
[personal profile] isaacschemm

Working in .NET, I've been in a situation where I need to implement a function in an interface that's supposed to return an IEnumerable<T>. (In some cases, I'd argue that IReadOnlyList<T> might make more sense - this way, the caller knows it's not going to be a lazily-evaluated sequence, and you can still return a .NET list, F# list, or array - but I digress).

Maybe the most obvious way to do this is by calling a function that explicitly returns an empty enumerable for you:

IEnumerable<string> SampleInterface.getAll() => Enumerable.Empty<string>();

In F#, it would be even shorter, because of the aggressive type resolution:

interface SampleInterface with
    member _.getAll() = Seq.empty

There are other clever ways to do the same thing, though, and it might just depend on what you think is the clearest or most readable - which might just mean keeping it consistent with the code around it. First, you can always expand out the function (because clearer isn't always shorter - I think it really does depend on the context of what's around it):

IEnumerable<string> SampleInterface.getAll() {
    return Enumerable.Empty<string>();
}

But there's also something clever you can do here, if you want to think of your code in a different way - where instead of resulting in "an empty list", it results in "no elements". C# lets you build iterator functions, where your code defines an IEnumerable<T> (and runs every time the resulting object is enumerated). Any function with a yield return or a yield break is treated in this way by the compiler. This means you can implement a function that returns "no elements" just by doing this:

IEnumerable<string> SampleInterface.getAll() {
    yield break;
}

It's a bit different in VB.NET, where iterator functions are denoted explicitly - so the yield break isn't needed:

Public Iterator Function getAll() As IEnumerable(Of String) Implements SampleInterface.getAll

End Function

That is, in a very literal sense, a function that returns no elements!

Funny thing is that there's no real equivalent to an empty iterator function in F# (not that you'd need it); the compiler won't allow a seq { } workflow without any elements in it, and suggests you use Seq.empty or the empty list [] instead.

isaacschemm: Drawing of myself as a snail (snail)
[personal profile] isaacschemm
Ascreenshot of the Artwork Inbox home page

Artwork Inbox is a web app I developed for my own use a few years ago. The idea behind Artwork Inbox is to let the user (a.k.a. me) view a social media feed in a way that separates the presentation of visual art (such as drawings or photographs), from other types of posts (like journal or status updates). Instead of simply sorting all posts by date and time, the app splits the feed into pages of 200 items each, and groups those items - first by type (visual or text) and then by author/artist. The current version is built on ASP.NET Core 7, with EF Core, Identity, and Cosmos DB.

Read more... )
Tags:
isaacschemm: Drawing of myself as a snail (snail)
[personal profile] isaacschemm

I started working on Looping Audio Converter back in 2015. Looping Audio Converter is designed to handle music files with seamless loops, and maintain those loops when converting from one format to another - usually when extracting music from one video game, with the intention of using it in another (this is why the default output format is the Wii's .brstm format and ADPCM codec). It's always been a little bit of a kludge, built from pieces that were floating around elsewhere: almost all input and output formats the program supports are handled by calling out to either a .NET library or a Windows executable to convert the input to 16-bit PCM, then again to convert that PCM data to the output format.

One important component of Looping Audio Converter is the included FFmpeg binary. FFmpeg is used to encode and decode certain formats (including FLAC, Ogg Vorbis, and AAC), but it's also used for most "effects" (like sample rate conversion and tempo and volume adjustment).

Read more... )
Tags:
isaacschemm: Drawing of myself as a snail (snail)
[personal profile] isaacschemm

Let's say you want to embed some videos on your website, and you want to put them in a list so people can click through and watch them.

Aset of three YouTube thumbnails. 1: "Summer CampIsland". 2: "Connecting a Bluetooth tape adapter to aBluetooth adapter for tape players". 3: "Are QuantumLeap and Gilmore Girls CONNECTED?"

The title, description, and thumbnail you give to the video are largely subjective decisions, but the duration - in minutes and seconds - is an objective property of the media itself, which means you should be able to extract it if you know the video's URL. But how exactly do you do that?

Well, the first thing you'll need to do is figure out what exactly you're dealing with: a raw video file (or stream) that plays in the browser's <video> tag, or a link to a page on a site like YouTube or Vimeo that hosts embeddable content. Technologically speaking, it's an entirely different beast. A YouTube page gives you the code for a player, and wraps all of it up with copy protection and a variety of other features specific to the platform. In other words, it's not handing the end user something to play; it's playing it for them. It's kind of like the difference between having a record of a song, and having a band come over with their own instruments to play it on.

SoI've got "Forever Your Girl" on CD, and also PaulaAbdul is in my kitchen. Not sure why.

That doesn't mean they can't serve the same purpose for the end user of your site, though, and in both cases it should be possible to programmatically determine the duration of the media. I've written a .NET library (ISchemm.DurationFinder) that handles this for you for a variety of common video types with just a URL; I'll walk through how it works overall, and how it finds the duration for each type of media that it supports.

Read more... )

Snail#

A programming blog where the gimmick is that I pretend to be a snail.

Syndicate

RSS Atom

Expand Cut Tags

No cut tags

Style Credit

Page generated Jun. 8th, 2025 07:33 pm
Powered by Dreamwidth Studios