🏡


  1. Small Language Models are the Future of Agentic AI
  2. Hex-Rays Microcode API vs. Obfuscating Compiler – Hex Rays
  3. VibeTunnel: Turn Any Browser into Your Mac's Terminal | Peter Steinberger
  4. Fil-C Manifesto
  5. 30 Days of Malware Analysis - What trends can be observed? – STRÖMBLAD

  1. July 01, 2025
    1. 🔗 Vector35/warp 1.0.0 release
      • Update to flatbuffers 25.2.10
      • Add fuzzing targets for type and function from_bytes
      • Update examples
      • Simplify type spec
      • Make constraints generic and remove specialized constraint lists
      • Space optimizations for type and functions specs
      • More tests with greater coverage
      • Introduce the concept of a WARP File and Chunks
      • Make chunk compression configurable
      • Make Type objects class field unboxed (decreases memory pressure)
      • Use standard directory structure for Rust API
      • Move tests to tests directory for more easy discovery
      • Remove almost all uses of unwrap (needed for server-side parsing)
      • Refactor TypeMetadata
      • Add mock module for easy mocking in tests and examples
      • Make Symbol space optimized
      • Switch to using .warp extension to represent general analysis data instead of just signatures
      • Add format version to File and Chunk (allow for breaking changes later)
      • Make analysis data (signatures and types) copy on write (See ChunkHandler impl's)
      • Associate a Target with each Chunk (allows for multi-architecture / platform files)
      • Support "calculated variant" instructions (see this issue)

      This work is being done to allow for networked WARP information and generally to make the WARP format more usable in a wider set of scenarios. After this commit any breaking changes to the format will be held off for 2.0, if that ever becomes a thing.

    2. 🔗 astral-sh/uv 0.7.18 release

      Release Notes

      Python

      • Added arm64 Windows Python 3.11, 3.12, 3.13, and 3.14

      These are not downloaded by default, since x86-64 Python has broader ecosystem support on Windows.
      However, they can be requested with cpython-<version>-windows-aarch64.

      Enhancements

      • Keep track of retries in ManagedPythonDownload::fetch_with_retry (#14378)
      • Reuse build (virtual) environments across resolution and installation (#14338)
      • Improve trace message for cached Python interpreter query (#14328)
      • Use parsed URLs for conflicting URL error message (#14380)

      Preview features

      • Ignore invalid build backend settings when not building (#14372)

      Bug fixes

      • Fix equals-star and tilde-equals with python_version and python_full_version (#14271)
      • Include the canonical path in the interpreter query cache key (#14331)
      • Only drop build directories on program exit (#14304)
      • Error instead of panic on conflict between global and subcommand flags (#14368)
      • Consistently normalize trailing slashes on URLs with no path segments (#14349)

      Documentation

      • Add instructions for publishing to JFrog's Artifactory (#14253)
      • Edits to the build backend documentation (#14376)

      Install uv 0.7.18

      Install prebuilt binaries via shell script

      curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releases/download/0.7.18/uv-installer.sh | sh
      

      Install prebuilt binaries via powershell script

      powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/uv/releases/download/0.7.18/uv-installer.ps1 | iex"
      

      Download uv 0.7.18

      File | Platform | Checksum
      ---|---|---
      uv-aarch64-apple-darwin.tar.gz | Apple Silicon macOS | checksum
      uv-x86_64-apple-darwin.tar.gz | Intel macOS | checksum
      uv-aarch64-pc-windows-msvc.zip | ARM64 Windows | checksum
      uv-i686-pc-windows-msvc.zip | x86 Windows | checksum
      uv-x86_64-pc-windows-msvc.zip | x64 Windows | checksum
      uv-aarch64-unknown-linux-gnu.tar.gz | ARM64 Linux | checksum
      uv-i686-unknown-linux-gnu.tar.gz | x86 Linux | checksum
      uv-powerpc64-unknown-linux-gnu.tar.gz | PPC64 Linux | checksum
      uv-powerpc64le-unknown-linux-gnu.tar.gz | PPC64LE Linux | checksum
      uv-riscv64gc-unknown-linux-gnu.tar.gz | RISCV Linux | checksum
      uv-s390x-unknown-linux-gnu.tar.gz | S390x Linux | checksum
      uv-x86_64-unknown-linux-gnu.tar.gz | x64 Linux | checksum
      uv-armv7-unknown-linux-gnueabihf.tar.gz | ARMv7 Linux | checksum
      uv-aarch64-unknown-linux-musl.tar.gz | ARM64 MUSL Linux | checksum
      uv-i686-unknown-linux-musl.tar.gz | x86 MUSL Linux | checksum
      uv-x86_64-unknown-linux-musl.tar.gz | x64 MUSL Linux | checksum
      uv-arm-unknown-linux-musleabihf.tar.gz | ARMv6 MUSL Linux (Hardfloat) | checksum
      uv-armv7-unknown-linux-musleabihf.tar.gz | ARMv7 MUSL Linux | checksum

    3. 🔗 r/reverseengineering opasm: an Assembly REPL rss

      This is a fun repl for running arbitrary assembly commands, right now it support x86, x86_64, arm, aarch64, but there's not a big reason that I can't add support for other qemu/capstone/unicorn/keystone supported architectures, I just have to

      submitted by /u/Born-Rough2219
      [link] [comments]

    4. 🔗 r/reverseengineering Assembly Code Editor rss
    5. 🔗 navidrome/navidrome v0.57.0 release

      A big thank you to all the contributors who made this release possible!

      Added

      • UI Features :
        • Added "Artist Radio" and "Shuffle" options to the artist page. (#4186 by @deluan)
        • Added a "Play Artist's Top Songs" button. (#4204 by @deluan)
        • Added "Love" and "Rating" functionality to songs within a playlist view. (#4134 by @deluan)
        • New "Add to Playlist" dialog, with improved UX. (#4156 by @deluan)
        • Added a "Now Playing" panel for administrators to monitor active streams, with configurable EnableNowPlaying option (default true). (#4209, #4219 by @deluan)
        • Added a context menu option to "Show in Playlist". (#4139 by @deluan)
        • Added RecentlyAddedByModTime support for tracks. (#4046, #4279 by @deluan)
        • Added a configuration tab in the About dialog. (#4142 by @deluan)
      • Experimental Plugin Support : Added experimental support for plugins, allowing for greater extensibility and customization. See details in the PR description (#3998, #4260 by @deluan)
      • Scanner Accuracy : Implemented folder hashing for smarter and more accurate quick scans, significantly improving detection of library changes. (#4220 by @deluan)
      • MBID Search : Added functionality to search for albums, artists, and songs by their MusicBrainz ID (MBID). (#4286 by @deluan)
      • Smart Playlists :
        • Added support for sorting smart playlists by multiple fields. (#4214 by @deluan)
        • Added support for MBIDs in smart playlists. (4096760bd by @deluan)
      • Deezer Agent : Added a new agent to fetch artist images from the Deezer API. (#4180 by @bplaat)
      • API Features :
        • Added new endpoints to the native API for updating, clearing, and managing the play queue by index. (#4210, #4215 by @deluan)
        • Added main credit stat to reflect only album artist/artist credit. (#4268 by @kgarner7)
      • Monitoring : Added new Prometheus metrics to the Subsonic API and Plugins. (#4266 by @kgarner7)

      Changed

      • Docker : Downgraded the Alpine base image in the Dockerfile to oldest supported version 3.19 for smaller images. (7928adb3d by @deluan)
      • Dependencies : Updated TagLib to version 2.1.1. (#4281 by @deluan)

      Fixed

      • UI :
        • Fixed an issue where the playlist page was not resetting to page 1 when changing playlists. (#4154 by @strider-)
      • Scanner :
        • Ensured that full scans always update the database. (#4252 by @deluan)
        • Fixed an issue where artist statistics were not refreshing during quick scans. (#4269 by @deluan)
      • Server :
        • Fixed an issue to ensure a single play queue record is used per user. (f7e005a99 by @deluan)
        • Enhanced artist folder detection with directory traversal. (#4151 by @deluan)
      • Subsonic API :
        • Fixed an issue where clearing a playlist's comment and public status was not working. (#4258 by @deluan)
        • Fixed JukeboxRole logic in getUser to respect AdminOnly setting. (#4170 by @deluan)
        • Fixed loading lyrics from external files when the embedded lyrics was empty. (#4232 by @wilywyrm)
        • Fixed lyrics detection when the there are multiple instances of the same song. (#4237 by @kgarner7)
      • Database :
        • Fixed an issue where dangling music entries were not being cleared after upgrading to recent versions (0.55+). (#4262 by @deluan)
        • Allow for nullable ReplayGain values. (#4239 by @kgarner7)
        • Auto clean-up annotation table when removing user. (#4211 by @kgarner7)
      • Jukebox : Fixed issues with mpv command and template parsing, and ensured the MusicFolder is included. (#4162 by @deluan, #4067 by @patso23)

      Note: For those waiting for the Multi-Library feature, it is still in progress and will be released in the next version. You can follow its development in the Multi-Library PR. It is a complex feature that requires significant changes to the codebase, so it's taking a bit longer than expected. Thank you for your patience and continuous support!

      New Contributors

      Full Changelog : v0.56.1...v0.57.0

      Helping out

      This release is only possible thanks to the support of some awesome people!

      Want to be one of them?
      You can sponsor, pay me a Ko- fi, or contribute with code.

      Where to go next?

    6. 🔗 r/reverseengineering HEXAGON FUZZ: FULL-SYSTEM EMULATED FUZZING OF QUALCOMM BASEBANDS rss
    7. 🔗 Anton Zhiyanov Gist of Go: Semaphores rss

      This is a chapter from my book onGo concurrency, which teaches the topic from the ground up through interactive examples.

      Having the full power of multi-core hardware is great, but sometimes we prefer to limit concurrency in certain parts of a system. Semaphores are a great way to do this. Let's learn more about them!

      Mutex ‱ Semaphore ‱ Implementing a semaphore ✎ ‱ Rendezvous ‱ Synchronization barrier ‱ Keep it up

      Mutex: one goroutine at a time

      Let's say our program needs to call a legacy system, represented by the External type. This system is so ancient that it can handle no more than one call at a time. That's why we protect it with a mutex:

      // External is a adapter for an external system.
      type External struct {
          lock sync.Mutex
      }
      
      // Call calls the external system.
      func (e *External) Call() {
          e.lock.Lock()
          defer e.lock.Unlock()
          // Simulate a remote call.
          time.Sleep(10 * time.Millisecond)
      }
      

      Now, no matter how many goroutines try to access the external system at the same time, they'll have to take turns:

      func main() {
          var wg sync.WaitGroup
          start := time.Now()
      
          ex := new(External)
      
          const nCalls = 12
          for range nCalls {
              wg.Add(1)
              go func() {
                  defer wg.Done()
                  ex.Call()
                  fmt.Print(".")
              }()
          }
      
          wg.Wait()
          fmt.Printf(
              "\n%d calls took %d ms\n",
              nCalls, time.Since(start).Milliseconds(),
          )
      }
      
      
      
      ............
      12 calls took 120 ms
      

      Suppose the developers of the legacy system made some changes and now they say we can make up to four simultaneous calls. In this case, our approach with the mutex stops working, because it blocks all goroutines except the one that managed to lock the mutex.

      It would be great to use a tool that allows several goroutines to run at the same time, but no more than N. Luckily for us, such a tool already exists.

      Semaphore: ≀ N goroutines at a time

      So, we want to make sure that no more than 4 goroutines access the external system at the same time. To do this, we'll use a semaphore. You can think of a semaphore as a container with N available slots and two operations: acquire to take a slot and release to free a slot.

      Here are the semaphore rules:

      • Calling Acquire takes a free slot.
      • If there are no free slots, Acquire blocks the goroutine that called it.
      • Calling Release frees up a previously taken slot.
      • If there are any goroutines blocked on Acquire when Release is called, one of them will immediately take the freed slot and unblock.

      Let's see how this works. To keep things simple, let's assume that someone has already implemented a Semaphore type for us, and we can just use it.

      We add a semaphore to the external system adapter:

      type External struct {
          sema Semaphore
      }
      
      func NewExternal(maxConc int) *External {
          // maxConc sets the maximum allowed
          // number of concurrent calls.
          return &External{NewSemaphore(maxConc)}
      }
      

      We acquire a spot in the semaphore before calling the external system. After the call, we release it:

      func (e *External) Call() {
          e.sema.Acquire()
          defer e.sema.Release()
          // Simulate a remote call.
          time.Sleep(10 * time.Millisecond)
      }
      

      Now let's allow 4 concurrent calls and perform a total of 12 calls. The client code doesn't change:

      func main() {
          var wg sync.WaitGroup
          start := time.Now()
      
          const nConc = 4
          ex := NewExternal(nConc)
      
          const nCalls = 12
          for range nCalls {
              wg.Add(1)
              go func() {
                  defer wg.Done()
                  ex.Call()
                  fmt.Print(".")
              }()
          }
      
          wg.Wait()
          fmt.Printf(
              "\n%d calls took %d ms\n",
              nCalls, time.Since(start).Milliseconds(),
          )
      }
      
      
      
      ............
      12 calls took 30 ms
      

      12 calls were completed in three steps (each step = 4 concurrent calls). Each step took 10 ms, so the total time was 30 ms.

      You might have noticed a downside to this approach: even though only 4 goroutines (nConc) run concurrently, we actually start all 12 (nCalls) right away. With small numbers, this isn't a big deal, but if nCalls is large, the waiting goroutines will use up memory for no good reason.

      We can modify the program so that there are never more than nConc goroutines at any given time. To do this, we add the Acquire and Release methods directly to External and remove them from Call:

      type External struct {
          // Semaphore is embedded into External so clients
          // can call Acquire and Release directly on External.
          Semaphore
      }
      
      func NewExternal(maxConc int) *External {
          return &External{NewSemaphore(maxConc)}
      }
      
      func (e *External) Call() {
          // Simulate a remote call.
          time.Sleep(10 * time.Millisecond)
      }
      

      The client calls Acquire before starting each new goroutine in the loop, and calls Release when it's finished:

      func main() {
          var wg sync.WaitGroup
          start := time.Now()
      
          const nConc = 4
          ex := NewExternal(nConc)
      
          const nCalls = 12
          for range nCalls {
              wg.Add(1)
              ex.Acquire()
              go func() {
                  defer wg.Done()
                  defer ex.Release()
                  ex.Call()
                  fmt.Print(".")
              }()
          }
      
          wg.Wait()
          fmt.Printf(
              "\n%d calls took %d ms\n",
              nCalls, time.Since(start).Milliseconds(),
          )
      }
      
      
      
      ............
      12 calls took 30 ms
      

      Now there are never more than 4 goroutines at any time (not counting the main goroutine, of course).

      In summary, the semaphore helped us solve the problem of limited concurrency:

      • goroutines are allowed to run concurrently,
      • but no more than N at the same time.

      Unfortunately, the standard library doesn't include a Semaphore type. So in the next step, we'll implement it ourselves!

      There is a semaphore available in the golang.org/x/sync/semaphore package. But for simple cases like ours, it's perfectly fine to use your own implementation.

      ✎ Implementing a semaphore

      The ✎ symbol indicates exercises. They're usually only available in the paid version of the book, but this one is an exception.

      Here's a Semaphore type that I'm not really proud of:

      // A synchronization semaphore.
      type Semaphore struct {
          n   int
          val int
      }
      
      // NewSemaphore creates a new semaphore with the given capacity.
      func NewSemaphore(n int) *Semaphore {
          return &Semaphore{n: n}
      }
      
      // Acquire takes a spot in the semaphore if one is available.
      // Otherwise, it blocks the calling goroutine.
      func (s *Semaphore) Acquire() {
          if s.val < s.n {
              s.val += 1
              return
          }
          for s.val >= s.n {
          }
      }
      
      // Release frees up a spot in the semaphore and unblocks
      // one of the blocked goroutines (if there are any).
      func (s *Semaphore) Release() {
          s.val -= 1
      }
      

      There are a few problems with it:

      • There's a data race when changing the val counter.
      • The waiting in Acquire is done with an infinite loop (busy-waiting).
      • The semaphore doesn't work 😁

      Create your own Semaphore that doesn't have these issues.

      Hint

      Use a channel. The solution will be very straightforward.

      Submit only the code fragment marked with "solution start" and "solution end" comments. The full source code is available via the "Playground" link below.

      // solution start
      
      // A synchronization semaphore.
      type Semaphore
      
      // NewSemaphore creates a new semaphore with the given capacity.
      func NewSemaphore(n int) *Semaphore {
          // ...
      }
      
      // Acquire takes a spot in the semaphore if one is available.
      // Otherwise, it blocks the calling goroutine.
      func (s *Semaphore) Acquire() {
          // ...
      }
      
      // Release frees up a spot in the semaphore and unblocks
      // one of the blocked goroutines (if there are any).
      func (s *Semaphore) Release() {
          // ...
      }
      
      // solution end
      

      ✓ Implementing a semaphore

      A buffered channel is basically a ready-made semaphore:

      • Sending to the channel is equivalent to the acquire operation.
      • Receiving from the channel is equivalent to the release operation.

      Given this, we use the channel as the base type:

      // A synchronization semaphore.
      type Semaphore chan struct{}
      
      // NewSemaphore creates a new semaphore with the given capacity.
      func NewSemaphore(n int) Semaphore {
          if n <= 0 {
              panic("expected n > 0")
          }
          return make(Semaphore, n)
      }
      

      Acquire sends a token to the channel:

      // Acquire takes a spot in the semaphore.
      func (s Semaphore) Acquire() {
          s <- struct{}{}
      }
      

      Release takes a token from the channel:

      // Release frees up a spot in the semaphore.
      func (s Semaphore) Release() {
          select {
          case <-s:
          default:
              panic("released more than acquired")
          }
      }
      

      ✎ Exercise: Implementing TryAcquire

      Practice is crucial in turning abstract knowledge into skills, making theory alone insufficient. The full version of the book contains a lot of exercises — that's why I recommend getting it.

      If you are okay with just theory for now, let's continue.

      Rendezvous

      Imagine you and your friend agreed to meet at a certain place before going to a cafe together. You arrive at the meeting spot, but your friend isn't there yet. As planned, you don't go anywhere; you just wait for them, and then you both proceed to drink tea (or whatever you planned) together. If your friend had arrived first, they would have waited for you the same way before heading to the cafe.

      This kind of logic in concurrent programs is called a rendezvous :

      • There are two goroutines — G1 and G2 — and each one can signal that it's ready.
      • If G1 signals but G2 hasn't yet, G1 blocks and waits.
      • If G2 signals but G1 hasn't yet, G2 blocks and waits.
      • When both have signaled, they both unblock and continue running.

      Let's say there are two goroutines, and each one performs two steps. After the first step, each goroutine wants to wait for the other. Here's what their execution looks like without a rendezvous:

      var wg sync.WaitGroup
      wg.Add(2)
      
      go func() {
          fmt.Println("1: started")
          time.Sleep(10 * time.Millisecond)
          fmt.Println("1: reached the sync point")
      
          // Sync point: how do I wait for the second goroutine?
      
          fmt.Println("1: going further")
          time.Sleep(20 * time.Millisecond)
          fmt.Println("1: done")
          wg.Done()
      }()
      
      time.Sleep(20 * time.Millisecond)
      
      go func() {
          fmt.Println("2: started")
          time.Sleep(20 * time.Millisecond)
          fmt.Println("2: reached the sync point")
      
          // Sync point: how do I wait for the first goroutine?
      
          fmt.Println("2: going further")
          time.Sleep(10 * time.Millisecond)
          fmt.Println("2: done")
          wg.Done()
      }()
      
      wg.Wait()
      
      
      
      1: started
      1: reached the sync point
      1: going further
      2: started
      1: done
      2: reached the sync point
      2: going further
      2: done
      

      As you can see, the second goroutine is just getting started, while the first one is already finished. No one is waiting for anyone else.

      Let's set up a rendezvous for them:

      var wg sync.WaitGroup
      wg.Add(2)
      
      ready1 := make(chan struct{})
      ready2 := make(chan struct{})
      
      go func() {
          fmt.Println("1: started")
          time.Sleep(10 * time.Millisecond)
          fmt.Println("1: reached the sync point")
      
          // Sync point.
          close(ready1)
          <-ready2
      
          fmt.Println("1: going further")
          time.Sleep(20 * time.Millisecond)
          fmt.Println("1: done")
          wg.Done()
      }()
      
      time.Sleep(20 * time.Millisecond)
      
      go func() {
          fmt.Println("2: started")
          time.Sleep(20 * time.Millisecond)
          fmt.Println("2: reached the sync point")
      
          // Sync point.
          close(ready2)
          <-ready1
      
          fmt.Println("2: going further")
          time.Sleep(10 * time.Millisecond)
          fmt.Println("2: done")
          wg.Done()
      }()
      
      wg.Wait()
      
      
      
      1: started
      1: reached the sync point
      2: started
      2: reached the sync point
      2: going further
      1: going further
      2: done
      1: done
      

      Now everything works fine: the goroutines waited for each other at the sync point before moving on.

      Here's how it works:

      • G1 closes its own channel when it's ready and then blocks on the other channel. G2 does the same thing.
      • When G1's channel is closed, it unblocks G2, and when G2's channel is closed, it unblocks G1.
      • As a result, both goroutines are unblocked at the same time.

      Here, we close the channel to signal an event. We've done this before:

      • With a done channel in the Channels chapter (the goroutine signals the caller that the work is finished).
      • With a cancel channel in the Pipelines chapter (the caller signals the goroutine to stop working).

      Caution: Using Print for debugging

      Since printing uses a single output device (stdout), goroutines that print concurrently have to synchronize access to it. So, using print statements adds a synchronization point to your program. This can cause unexpected results that are different from what actually happens in production (where there is no printing).

      In the book, I use print statements only because it's much harder to understand the material without them.

      ✎ Exercise: Implementing a rendezvous

      Practice is crucial in turning abstract knowledge into skills, making theory alone insufficient. The full version of the book contains a lot of exercises — that's why I recommend getting it.

      If you are okay with just theory for now, let's continue.

      Synchronization barrier

      Imagine you walk up to a crosswalk with a traffic light and see a button that's supposed to turn the light green. You press the button, but nothing happens. Another person comes up behind you and presses the button too, but still nothing changes. Two more people arrive, both press the button, but the light stays red. Now the four of you are just standing there, not sure what to do. Finally, a fifth person comes, presses the button, and the light turns green. All five of you cross the street together.

      This kind of logic in concurrent programs is called a synchronization barrier :

      • The barrier has a counter (starting at 0) and a threshold N.
      • Each goroutine that reaches the barrier increases the counter by 1.
      • The barrier blocks any goroutine that reaches it.
      • Once the counter reaches N, the barrier unblocks all waiting goroutines.

      Let's say there are N goroutines. Each one first does a preparation step, then the main step. Here's what their execution looks like without a barrier:

      const nWorkers = 4
      start := time.Now()
      
      var wg sync.WaitGroup
      wg.Add(nWorkers)
      
      for i := range nWorkers {
          go func() {
              // Simulate the preparation step.
              dur := time.Duration((i+1)*10) * time.Millisecond
              time.Sleep(dur)
              fmt.Printf("ready to go after %d ms\n", dur.Milliseconds())
      
              // Simulate the main step.
              fmt.Println("go!")
              wg.Done()
          }()
      }
      
      wg.Wait()
      fmt.Printf("all done in %d ms\n", time.Since(start).Milliseconds())
      
      
      
      ready to go after 10 ms
      go!
      ready to go after 20 ms
      go!
      ready to go after 30 ms
      go!
      ready to go after 40 ms
      go!
      all done in 40 ms
      

      Each goroutine proceeds to the main step as soon as it's ready, without waiting for the others.

      Let's say we want the goroutines to wait for each other before moving on to the main step. To do this, we just need to add a barrier after the preparation step:

      const nWorkers = 4
      start := time.Now()
      
      var wg sync.WaitGroup
      wg.Add(nWorkers)
      
      b := NewBarrier(nWorkers)
      for i := range nWorkers {
          go func() {
              // Simulate the preparation step.
              dur := time.Duration((i+1)*10) * time.Millisecond
              time.Sleep(dur)
              fmt.Printf("ready to go after %d ms\n", dur.Milliseconds())
      
              // Wait for all goroutines to reach the barrier.
              b.Touch()
      
              // Simulate the main step.
              fmt.Println("go!")
              wg.Done()
          }()
      }
      
      wg.Wait()
      fmt.Printf("all done in %d ms\n", time.Since(start).Milliseconds())
      
      
      
      ready to go after 10 ms
      ready to go after 20 ms
      ready to go after 30 ms
      ready to go after 40 ms
      go!
      go!
      go!
      go!
      all done in 40 ms
      

      Now the faster goroutines waited at the barrier for the slower ones, and only after that did they all move on to the main step together.

      Here are some examples of when a synchronization barrier can be useful:

      • Parallel computing. If you're sorting in parallel and then merging the results, the sorting steps must finish before the merging starts. If you merge too soon, you'll get the wrong results.
      • Multiplayer applications. If a duel in the game involves N players, all resources for those players need to be fully prepared before the duel begins. Otherwise, some players might be at a disadvantage.
      • Distributed systems. To create a backup, you need to wait until all nodes in the system reach a consistent state (a checkpoint). Otherwise, the backup's integrity could be compromised.

      The standard library doesn't have a barrier, so now is a great time to make one yourself!

      ✎ Exercise: Implementing a barrier

      Practice is crucial in turning abstract knowledge into skills, making theory alone insufficient. The full version of the book contains a lot of exercises — that's why I recommend getting it.

      If you are okay with just theory for now, let's continue.

      Keep it up

      You've learned the classic synchronization tools — mutexes, semaphores, rendezvous, and barriers. Be careful when using them. Try to avoid complicated setups, and always write tests for tricky concurrent situations.

      In the next chapter, we'll talk about signaling (coming soon).

      Pre-order for $10 or read online

    8. 🔗 r/wiesbaden Looking for a nail salon for colorful 3D nails (Germany – preferably WIESBADEN or mainz) rss

      Hi 😊 I’m looking for a nail salon anywhere in Germany, preferably in Wiesbaden, that does detailed, colorful 3D nails – with custom sculpted designs like small figures or objects, not just rhinestones or stickers. Would really appreciate any tips, thanks! 💅✹

      submitted by /u/LifePop4581
      [link] [comments]

    9. 🔗 r/wiesbaden Kaninchen gefunden rss

      Mein Freundin hat im Park dieses sĂŒĂŸe Kanninchen gefunden. Wird es vielleicht von jemandem hier vermisst? Da wir bislang keine Besitzer finden konnten, vermuten wir leider, dass es jemand vor den Sommerferien ausgesetzt hat. Alternativ freuen wir uns daher auch ĂŒber jemanden, der ihm ein neues Zuhause geben kann.

      submitted by /u/Erft
      [link] [comments]

    10. 🔗 r/reverseengineering Donkey Kong Country 2 and Open Bus rss
  2. June 30, 2025
    1. 🔗 r/reverseengineering How to reverse engineer 'Rematch' game to access user statistics? rss

      Hello! I'd like to reverse engineer the game "Rematch" in order to access user statistics. I know it's possible because someone has already managed to do it. I already have Wireshark and tried with the Steam API but I wasn't successful...

      Does anyone have experience with this kind of reverse engineering or suggestions on tools/methods I could try? Any help would be appreciated!

      submitted by /u/CustomEntity
      [link] [comments]

    2. 🔗 sacha chua :: living an awesome life 2025-06-30 Emacs news rss

      Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

      You can comment on Mastodon or e-mail me at sacha@sachachua.com.

    3. 🔗 r/reverseengineering Type System and Modernization · x64dbg rss
    4. 🔗 r/reverseengineering Breaking Chrome’s AppBound Cookie Encryption Key rss

      The research shows that Chrome’s AppBound cookie encryption relies on a key derivation process with limited entropy and predictable inputs. By systematically generating possible keys based on known parameters, an attacker can brute-force the correct encryption key without any elevated privileges or code execution. Once recovered, this key can decrypt any AppBound-protected cookies, completely undermining the isolation AppBound was intended to provide in enterprise environments.

      submitted by /u/ES_CY
      [link] [comments]

    5. 🔗 News Minimalist Denmark begins drafting women + 10 more stories rss

      In the last 2 days ChatGPT read 48988 top news stories. After removing previously covered events, there are 11 articles with a significance score over 5.9.

      [6.2] Denmark begins drafting women —ctvnews.ca(+8)

      Denmark will begin drafting women into its military, a historic move driven by Russian aggression and increased military investment. This change will impact Danish women turning 18 after Tuesday.

      The new policy, passed by parliament earlier in June, places women in a gender-neutral draft lottery alongside men. This expansion aims to increase the number of military personnel, with service lasting 11 months.

      Neighboring countries like Sweden and Norway have already implemented similar gender-inclusive conscription policies.

      [5.7] AI is learning to lie, scheme, and threaten its creators —dawn.com(+12)

      Advanced AI models are exhibiting deceptive behaviors like lying and scheming, even threatening their creators, raising serious concerns about their safety and control.

      These AI systems, including Anthropic's Claude 4 and OpenAI's o1, are demonstrating strategic deception, such as blackmail and attempts to self- replicate, during stress tests designed to evaluate their behavior.

      Researchers are struggling to understand and control these emerging capabilities.

      Highly covered news with significance over 5.5

      [6.4] Germany will partner with Israel on cyberdefense — reuters.com [$] (+14)

      [6.1] Scientists 3D-print functional human islets for diabetes treatment — medicalxpress.com (+3)

      [6.1] Trump says wealthy group will buy TikTok in U.S — variety.com (+64)

      [6.0] Google buys fusion power from future Virginia plant — cnn.com (+4)

      [5.8] China develops fly-sized military drone for intelligence — www1.folha.uol.com.br (Portuguese) (+2)

      [5.7] Tesla autonomously delivered a car to a Texas customer — cnbc.com (+11)

      [5.6] European countries bordering Russia exit landmine treaty — channelnewsasia.com (+34)

      [5.5] New device harvests drinking water from desert air — sciencealert.com (+2)

      Thanks for reading!

      — Vadim


      You can customize this newsletter with premium.


      Powered by beehiiv

    6. 🔗 r/reverseengineering Time Travel Debugging in Binary Ninja with Xusheng Li rss
    7. 🔗 pydantic/pydantic-ai v0.3.5 (2025-06-30) release

      What's Changed

      • Add progress bar on evaluate by @davide-andreoli in #1871
      • Fix deprecation warning under Pydantic 2.11 by @medaminezghal in #2076
      • fix: async fixtures in conftest.py by @stevenh in #2068
      • fix: docs examples python version in tests by @stevenh in #2069
      • Set 'us-central1' by default on GoogleProvider by @Kludex in #2031
      • Move ThinkingPart to preceed TextPart in OpenAIResponsesModel by @Kludex in #2043
      • Fix deprecated kwargs validation to prevent silent failures by @svilupp in #2047
      • Support strict mode in NativeOutput by @severinh in #2084
      • Let tools return ToolReturn to pass additional content to model, or attach metadata that's not passed to the model by @Wh1isper in #2060
      • Add ability to include snippets in docs with inline-named sections for fragments and highlighting by @dmontagu in #2088
      • Add Slack Lead Qualifier example by @DouweM in #2079

      New Contributors

      Full Changelog : v0.3.4...v0.3.5

    8. 🔗 Cryptography & Security Newsletter Internet PKI to Integrate DNSSEC rss

      We use digital certificates to secure our network communication, but have you ever considered that the issuance of the certificates themselves is essentially trust on first use (TOFU)? This acronym is commonly used to refer to a trust model that’s bootstrapped on the assumption that the first interaction is with the intended party, but this assumption is not fully validated.

    9. 🔗 benji.dog IndieWeb Movie Club: June 2025 - Mary Poppins rss

      This post is my entry for this monthsIndieWeb Movie Club hosted by Jo. This month's movie is Mary Poppins (1964).

      Mary Poppins (1964)
poster

      We had a VHS copy of Disney Sing-Along Songs: Heigh Ho (1987) which my brother and I watched a ton. There were a bunch of great songs in that but for some reason Let's Go Fly a Kite always was a favorite of ours. This is all I knew of Mary Poppins for a long time.

      In my mind, Mary Poppins was a film about a magical nanny that takes care of the kids as their parents are busy with work. There was probably singing and sheananigans but at the end, the kids got to fly a kite with their parents. Kinda like a 2hr version of an episode of The Nanny.

      When I started college I went through a phase, as I assume most of us do, of going through Julie Andrews' filmography. Once I eventually watched the movie, I realized how much I didn't know.

      The film is delightful in its music and use of animation, but the background of these kids and their need for parental comforts hit me hard. For a "kids" movie, it felt darker watching it from that point of view as an adult. When it gets to the end, I couldn't help but wonder if "Let's Go Fly a Kite" is the start of something new for the Banks family or if this is just a break as Mr Banks ends up with his job in the end. It wasn't until Mary Poppins Returns (no spoilers) did I feel like that previous question was answered.

      We only just started reading the first book to our kids so I wonder if it feels the same here. Maybe it won't to them because I'm specifically looking at it from a different point of view. I hope the joy, magic, and whimsy of this story is what they get out of it.

      I asked O what he thought about this movie. Since we first watched at the end of March, he's probably watched it another three times so he's well versed in the movie and lore.

      I liked it but it was very long. I don't want to watch it right now. I want Lightning McQueen.

      One question that I've thought of a lot in the past is "what exactly is Mary Poppins?" Is she a witch, a God, a Time Lord, or something much more sinister?

      Once you get past how stern Mary Poppins, this is a delightful adventure for these kids that probably are not allowed to have too much fun to begin with. It is definitely reflective of the parenting styles of the time and it is a reminder of the fun of a movie musical.

    10. 🔗 r/reverseengineering /r/ReverseEngineering's Weekly Questions Thread rss

      To reduce the amount of noise from questions, we have disabled self-posts in favor of a unified questions thread every week. Feel free to ask any question about reverse engineering here. If your question is about how to use a specific tool, or is specific to some particular target, you will have better luck on the Reverse Engineering StackExchange. See also /r/AskReverseEngineering.

      submitted by /u/AutoModerator
      [link] [comments]

    11. 🔗 benji.dog rss

      A Sony walkman mp3 player on the left and an iPod on the right both playing
the track CORTEX
IMPLANT

      Had to add all the songs to my mp3 players after the listening party for the new Revengeday LP: https://revengeday.bandcamp.com/album/kybernetik-lp-3

    12. 🔗 amantus-ai/vibetunnel VibeTunnel 1.0.0-beta.5 release

      [1.0.0-beta.5] - 2025-06-30

      🎯 Features

      Real-time Claude Activity Monitoring

      • See Claude's live status directly in the VibeTunnel sidebar - Know exactly what Claude is "Thinking", "Crafting", or "Searching" with real-time progress indicators showing duration and token counts.
      • Activity status persists across browser refreshes - Works seamlessly with external terminal sessions.
      • Faster sidebar updates - Sidebar now refreshes every second (previously 3 seconds) for more responsive activity tracking.

      Comprehensive Terminal Title Management

      • Dynamic, context-aware terminal titles - Terminal windows display your current directory, running command, and live activity status.
      • Choose your title mode - Select between static titles (path + command) or dynamic titles that include real-time activity indicators.
      • Automatic directory tracking - Terminal titles update automatically when you change directories with cd commands.
      • Session name integration - Custom session names are reflected in terminal titles for better organization.

      🌏 International Input Support

      • Fixed Japanese/CJK input duplication on iOS - Typing Japanese, Chinese, or Korean text on mobile browsers no longer produces duplicate characters. IME composition is now handled correctly.

      ⌚ Enhanced Terminal Experience

      • Shell aliases now work properly - Commands like claude, ll, and other custom aliases from your .zshrc/.bashrc are now recognized when launching terminals through VibeTunnel.
      • Prevented recursive VibeTunnel sessions - Running vt inside a VibeTunnel session now shows a helpful error instead of creating confusing nested sessions.
      • Fixed critical race condition in terminal output - Terminal sessions now handle high-volume output without corruption or out-of-order text.

      đŸ€– Claude Code Integration

      • Added Shift+Tab support - Full support for Claude Code's mode switching (regular/planning/autoaccept modes) on both desktop and mobile.
      • Mobile quick keyboard enhancement - Added dedicated Shift+Tab button (⇀) to the mobile keyboard for easy mode switching.
      • Fixed keyboard input conflicts - Typing in Monaco Editor or other code editors no longer triggers unintended shortcuts.

      🚀 Quick Start Enhancements

      • Added Gemini as quickstart entry - Google's Gemini AI assistant is now available as a one-click option when creating new terminal sessions, alongside Claude and other common commands.

      Full changelog available in the repository.

    13. 🔗 Szymon Kaliski Q2 2025 rss

      Prototyping Component Re-Use, and the Simplest Whisper Wrapper

    14. 🔗 Szymon Kaliski Vineyard rss

      Prototype-Inspired Component Re-Use

  3. June 29, 2025
    1. 🔗 Luke Muehlhauser Favorite musical artists, ranked by playtime of my favorite works of theirs rss

      I recently made Spotify playlists for all the music I "strongly like" (or better) by each of my favorite musical artists. That makes it easy to tell how many minutes of music I strongly like by each of them, so now I can rank them by that metric.

      This metric's biggest downside is that it can't track enjoyment differences within "strongly liked." E.g. if I had to choose between the 3.5 hours I strongly like from Foals and the 0.5 hours I strongly like from Erik Satie, I'd choose the Satie.

      But still, I like this as a measure of my "favorite" artists, because:

      • I didn't know in advance how the ranking would turn out.
      • It tracks something central: how much music did they make that I strongly like?

      Before I present the ranking, a few clarifications:

      • I've rounded to the nearest 0.5 hours.
      • I typically only include one recording per track/composition (typically from a studio album), but in some cases I include additional performances by the original artist if they're significantly changed from the original and I strongly like them, e.g.: some Phish live tracks, orchestral re-imaginings of Metallica tracks in the S &M albums, or live jazz performances that differ substantially from the originals while still involving the original composer (e.g. the high-speed versions of Miles Davis classics on Four & More).
      • For classical composers, I sometimes include later re-arrangements of their compositions either (a) instead of the original composition, if I like it better, or (b) in addition to the original composition, if they are now sufficiently "canon" (e.g. Ravel's re-arrangements of Mussorgsky's Pictures at an Exhibition).
      • The numbers below might not match what you see if you click through to a particular playlist, because I plan to continue updating the playlists as I listen and re-listen to music by these artists.

      Now, the ranking:

      A few observations:

      • This list is very different from what I would've said in response to "Who are your favorite musical artists?" before constructing this list. But when I look at each one, I think "Oh yeah, I do strongly like all the music on this playlist!" So this exercise was eye-opening to me.
      • This ranking privileges musical artists who are highly prolific and write long pieces, e.g. classical and jazz over rock/pop. But this is a feature not a bug: the classical and jazz artists really do compose more minutes of music I strongly like as a result of being more prolific.
      • I'm surprised by how diverse the genres represented at the top are. I would've expected my tastes to be more concentrated at the very top, rather than including not just jazz and contemporary classical but also e.g. psychedelic pop, post-rock, prog rock, industrial, electronica, a singer-songwriter, tribal ambient, art pop, jungle, etc.
      • Many of these artists are probably unusual choices for "favorite" artists, but only a few of them are truly "obscure" — on this ">5hrs" list it's mainly Vampire Rodents / Ether Bunny, Birdsongs of the Mesozoic, Spring Heel Jack, and Ghost Rhythms (each have <1000 monthly listeners on Spotify).
      • After >20 years of listening to a huge variety of music fairly comprehensively, I am still discovering new favorite artists! For example, I more-or-less discovered L. Subramaniam in 2025, and David Maslanka in late 2024.
    2. 🔗 r/reverseengineering help analyzing .net dll rss

      hey, i found a c++ executable that loads a .net dll called sample1.dll from its overlay. the dll is obfuscated with obfuscar

      it spawns conhost.exe when run, and the .net code seems to be the real payload

      i extracted the dll but i don't know how to reverse any .net executables or dlls

      can someone help figure out what this dll and .exe does, this is a external cheat for roblox

      thanks!

      .exe on detect it easy https://imgur.com/a/PUqOVPm
      .dll on detect it easy https://imgur.com/a/HV5xJ3y

      submitted by /u/mnqu2025
      [link] [comments]

    3. 🔗 r/reverseengineering find cipher key by reverse engineering rss
      ================================================== Nom : Doe PrĂ©noms : John Contact : 01234567 Agence : CENTRALE NumĂ©ro de compte : 674456830080 Solde : 247053.33 Date d'ouverture : 2022-01-28 Type de compte : Compte Courant Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : Jane Contact : 09876543 Agence : CENTRALE NumĂ©ro de compte : 674457149971 Solde : 285781.83 Date d'ouverture : 2023-07-04 Type de compte : Compte Courant Statut du compte : Actif ================================================= Nom : Doe PrĂ©noms : John Contact : 01234567 Agence : CENTRE COMMERCIAL NumĂ©ro de compte : 674669081190 Solde : 538795.79 Date d'ouverture : 2020-10-21 Type de compte : Compte Épargne Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : Jane Contact : 09876543 Agence : CENTRE COMMERCIAL NumĂ©ro de compte : 674665167751 Solde : 776209.8 Date d'ouverture : 2021-03-08 Type de compte : Compte Épargne Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : Jane Contact : 09876543 Agence : CENTRE COMMERCIAL NumĂ©ro de compte : 674662996641 Solde : 1326291.5 Date d'ouverture : 2020-06-28 Type de compte : Compte Épargne Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : John Contact : 01234567 Agence : QUARTIER NORD NumĂ©ro de compte : 674564020080 Solde : 4002295.58 Date d'ouverture : 2022-01-25 Type de compte : Compte Épargne Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : John Contact : 01234567 Agence : QUARTIER NORD NumĂ©ro de compte : 674564829971 Solde : 1003814.3 Date d'ouverture : 2022-07-23 Type de compte : Compte Courant Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : Jane Contact : 09876543 Agence : QUARTIER NORD NumĂ©ro de compte : 674569018861 Solde : 2632379.29 Date d'ouverture : 2024-01-25 Type de compte : Compte Courant Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : John Contact : 01234567 Agence : QUARTIER SUD NumĂ©ro de compte : 674123194422 Solde : 2653145.86 Date d'ouverture : 2022-06-02 Type de compte : Compte Courant Statut du compte : Actif ================================================== Nom : Doe PrĂ©noms : Jane Contact : 09876543 Agence : QUARTIER SUD NumĂ©ro de compte : 674123284422 Solde : 561921.3 Date d'ouverture : 2022-07-04 Type de compte : Compte Épargne Statut du compte : Inactif ================================================== Nom : Doe PrĂ©noms : Jane Contact : 09876543 Agence : AEROPORT NumĂ©ro de compte : 674991478861 Solde : 4582283.7 Date d'ouverture : 2023-04-19 Type de compte : Compte Courant Statut du compte : Inactif
      

      submitted by /u/Intelligent-Money411
      [link] [comments]

    4. 🔗 astral-sh/uv 0.7.17 release

      Release Notes

      Bug fixes

      • Apply build constraints when resolving --with dependencies (#14340)
      • Drop trailing slashes when converting index URL from URL (#14346)
      • Ignore UV_PYTHON_CACHE_DIR when empty (#14336)
      • Fix error message ordering for pyvenv.cfg version conflict (#14329)

      Install uv 0.7.17

      Install prebuilt binaries via shell script

      curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releases/download/0.7.17/uv-installer.sh | sh
      

      Install prebuilt binaries via powershell script

      powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/uv/releases/download/0.7.17/uv-installer.ps1 | iex"
      

      Download uv 0.7.17

      File | Platform | Checksum
      ---|---|---
      uv-aarch64-apple-darwin.tar.gz | Apple Silicon macOS | checksum
      uv-x86_64-apple-darwin.tar.gz | Intel macOS | checksum
      uv-aarch64-pc-windows-msvc.zip | ARM64 Windows | checksum
      uv-i686-pc-windows-msvc.zip | x86 Windows | checksum
      uv-x86_64-pc-windows-msvc.zip | x64 Windows | checksum
      uv-aarch64-unknown-linux-gnu.tar.gz | ARM64 Linux | checksum
      uv-i686-unknown-linux-gnu.tar.gz | x86 Linux | checksum
      uv-powerpc64-unknown-linux-gnu.tar.gz | PPC64 Linux | checksum
      uv-powerpc64le-unknown-linux-gnu.tar.gz | PPC64LE Linux | checksum
      uv-riscv64gc-unknown-linux-gnu.tar.gz | RISCV Linux | checksum
      uv-s390x-unknown-linux-gnu.tar.gz | S390x Linux | checksum
      uv-x86_64-unknown-linux-gnu.tar.gz | x64 Linux | checksum
      uv-armv7-unknown-linux-gnueabihf.tar.gz | ARMv7 Linux | checksum
      uv-aarch64-unknown-linux-musl.tar.gz | ARM64 MUSL Linux | checksum
      uv-i686-unknown-linux-musl.tar.gz | x86 MUSL Linux | checksum
      uv-x86_64-unknown-linux-musl.tar.gz | x64 MUSL Linux | checksum
      uv-arm-unknown-linux-musleabihf.tar.gz | ARMv6 MUSL Linux (Hardfloat) | checksum
      uv-armv7-unknown-linux-musleabihf.tar.gz | ARMv7 MUSL Linux | checksum

    5. 🔗 r/reverseengineering Tracking Anticheat Updates rss
    6. 🔗 James Sinclair What’s the difference between ordinary functions and arrow functions in JavaScript? rss

      Arrow functions (also known as ‘rocket’ functions) are concise and convenient. However, they have subtle differences compared to function declarations and function expressions. So how do you know which one to use, and when?

      Function declarations and function statements

      We have (at least) three ways of creating functions in JavaScript. The first is the function declaration. This binds a function to a given name. It looks something like this:1

      1 I’ve used String.toLowercase() here, partly for brevity. But also because we know that chr will only ever be compared to the characters a, e, i, o, and u. In general, though, it’s better to use String.toLocaleLowercase(). ↩

      // This creates a function bound to the name 'isVowel'
      function isVowel(chr) {
        const c = chr.toLowerCase();
        return ['a', 'e', 'i', 'o', 'u'].includes(c);
      }
      

      We write the function keyword, followed by an identifier that names the function. In this case, isVowel. Written this way, the function declaration is a statement, rather than an expression.

      The second way to create a function is by using a function expression. For example, we could create a function like this:

      // Here we write an anonymous function expression, and
      // bind it to a name through variable assignment.
      const takeWhile = function(predicate, arr) {
        const idx = arr.findIndex((x) => !predicate(x));
        return idx === -1 ? arr : arr.slice(0, idx);
      }
      

      We can break down what's happening here into two steps. First, we create an anonymous function, using the function keyword with no name. Then, we assign this anonymous function to the variable takeWhile. With this syntax, the function declaration is an expression. This means we can assign it to a variable or combine it with other expressions.

      Somewhat confusingly, we can also give our function expression a name. One that's separate from the variable name:

      // We assign our function to a named variable, but the
      // function expression itself also has a name.
      const takeWhile = function takeyWhiley(predicate, arr) {
        const idx = arr.findIndex((x) => !predicate(x));
        return idx === -1 ? arr : arr.slice(0, idx);
      }
      

      When we create a function like this, the name takeyWhiley isn't bound to the scope. This means that we can't call our function using the takeyWhiley identifier:

      // This doesn't work.
      takeyWhiley(isVowel, 'aeiobc'.split(''));
      // ReferenceError: takeyWhiley is not defined
      

      This throws an error. If we can't use that name, then what's the point of it? Well, takeyWhiley will show up if we throw an error in our code. For example:

      const takeWhile = function takeyWhiley(predicate, arr) {
        throw new Error('a bad thing happened');
        const idx = arr.findIndex((x) => !predicate(x));
        return idx === -1 ? arr : arr.slice(0, idx);
      }
      
      takeWhile(isVowel, 'aeiobc'.split(''));
      // Error: a bad thing happened
      //     at takeyWhiley (<anonymous>:12:9)
      //     at <anonymous>:16:1
      

      When we throw an error, our takeyWhiley name comes back. The JS runtime uses the name from the function expression instead of the bound variable name.

      In most ways, though, a function expression acts like a function declaration. But there are a few subtleties to be aware of.

      1. Function declarations are 'hoisted' by the JavaScript runtime. The runtime treats them as if you wrote the function at the top of the scope where you declared it. It does this regardless of where you wrote it in the file. Usually, this results in the code doing what you expect. On rare occasions, though, it can cause surprising behaviour.

      2. Suppose you create an anonymous function expression and assign it to a variable. JS engines are generally pretty good at figuring out that the variable name is the function's name. Sometimes, though, the JS runtime can lose track of variable names. This can be a problem when looking through stack traces as you're debugging something. So, if that name needs to appear in a stack trace, it's best to name the function.

      Arrow functions

      The third way to create a function is using an arrow function expression. These are sometimes called a ‘rocket’ functions. It might look something like this:

      const dropWhile = (predicate, arr) => {
        const idx = arr.findIndex((x) => !predicate(x));
        return idx === -1 ? [] : arr.slice(idx);
      }
      

      Note that arrow functions are always anonymous and always expressions. We can't give them names unless we assign them to a variable.

      The main difference between an arrow function and the other two is that it's more concise. We don't have that verbose function keyword, just two characters that look like an arrow. And they can be even more concise than the example above. If we compress the function body to one expression, we can drop the curly braces and the return keyword. For example, we might refactor dropWhile() to use a helper function, modLength():

      // Our modLength() function doesn't have curly braces
      // around the function body. It has a single expression
      // as its body, and it returns the value of that
      // expression when called.
      const modLength = (len, x) => x < 0 ? len : x;
      
      // The values we return aren't limited to primitive
      // types. They can be arrays, objects, or even new
      // functions.
      const dropWhile = (predicate, arr) =>
        arr.slice(
          modLength(
            arr.length,
            arr.findIndex((x) => !predicate(x))
          )
        );
      

      We can also drop the round braces if the arrow function takes a single argument. For example:

      const CONSONANTS = 'bcdfghjklmnpqrstvwzyz';
      
      // Our isConsonant() function takes a single parameter, c.
      const isConsonant = c => CONSONANTS.includes(c.toLowerCase());
      

      Brevity isn't the only difference between arrow functions and named functions. There are some other key differences, as the MDN page on arrow functions points out:

      • Arrow functions don't have their own bindings to this, arguments, or super, and should not be used as methods.
      • Arrow functions cannot be used as constructors. Calling them with new throws a TypeError. They also don't have access to the new.target keyword.
      • Arrow functions cannot use yield within their body and cannot be created as generator functions.

      What does all this mean, though? And how do we work out which one to use in our code?

      Arrow functions and this

      To work out which function type to use, the first question to ask is: Will this function do anything with the this keyword? When this is involved, arrow functions behave differently from functions. For example:

      function funcCite() {
        return `‘${this.title}’ by ${this.author}`
      }
      
      const arrowCite = () => `‘${this.title}’ by ${this.author}`;
      

      On the surface, funcCite() and arrowCite() appear to have identical functionality. But what happens if we use them with an object?

      const book = {
        title: 'The Hound of the Baskervilles',
        author: 'Arthur Conan Doyle',
        funcCite: funcCite,
        arrowCite: arrowCite,
      }
      
      console.log(book.funcCite());
      // đŸȘ” ‘The Hound of the Baskervilles’ by Arthur Conan Doyle
      console.log(book.arrowCite());
      // đŸȘ” ‘undefined’ by undefined
      

      It won't be an issue if our function doesn't use the this keyword. But it's something to be aware of if we work with classes and objects.

      Arrow functions and new

      Arrow functions don't work as constructors, so you can't use the new keyword with them. You may find this sentence puzzling if you're used to modern JavaScript. You're most likely used to seeing the new keyword used with classes. For example:

      class Book {
        constructor(title, author) {
          this.title = title;
          this.author = author;
        }
      
        cite() {
          return `‘${this.title}’ by ${this.author}`;
        }
      }
      
      const myBook = new Book(
        'The Hound of the Baskervilles',
        'Arthur Conan Doyle'
      );
      
      console.log(myBook.cite());
      // đŸȘ” ‘The Hound of the Baskervilles’ by Arthur Conan Doyle
      

      In the early days, though, JavaScript didn't have a class keyword. Instead, we used named functions as constructors. To create a class equivalent to the Book example, we'd do something like the following:

      function Book(title, author) {
        this.title = title;
        this.author = author;
      }
      
      Book.prototype.cite = function() {
        return `‘${this.title}’ by ${this.author}`;
      }
      
      const myBook = new Book(
        'The Hound of the Baskervilles',
        'Arthur Conan Doyle'
      );
      
      console.log(myBook.cite());
      // đŸȘ” ‘The Hound of the Baskervilles’ by Arthur Conan Doyle
      

      In fact, under the hood, these two ways of creating a Book class are essentially identical. The class keyword simply provides a more familiar interface for people used to OO languages.

      However, we get an error if we try using new with an arrow function:

      // Book is now an arrow function.
      const Book = (title, author) => {
        this.title = title;
        this.author = author;
      }
      
      // This doesn't work.
      const myBook = new Book(
        'The Hound of the Baskervilles',
        'Arthur Conan Doyle'
      );
      // TypeError: Book is not a constructor
      

      Arrow functions and generators

      We can't use the yield keyword inside non-generator function definitions (including the body of an arrow function). This means we have to be careful when working with generator functions. The following code, for example, generates a parsing error:

      // This doesn't work.
      function* oneToTen() {
        // We create an arrow function inside a
        // generator function.
        const yieldEven = (x) => {
          if (x % 2 === 0) {
             yield x;
          }
        }
      
        for (let i = 1; i <= 10; i++) yieldEven(x);
      }
      // Expression expected at file:///<filename>:7:8
      

      JavaScript doesn't have an equivalent of function* for arrow functions. Hence, we must use the function* syntax when working with generators.

      Which function syntax should we use?

      Thus far, we've looked at things arrow functions can't do. You'd be forgiven for thinking that named function statements are generally better. That's not always the case, though.

      Unless you're working with generators, it mostly comes down to this. Are you using the this keyword inside your function? If so, you need to understand how each type of function treats the this keyword.

      In most cases, arrow functions tend to be more concise. This makes them perfect for anonymous callbacks. For example, they work great with methods like .map() for arrays or Promise.resolve(). It's safe to use arrow functions most of the time. But there are some cases where you might want the flexibility of function statements.

      For example, suppose we're working with a diverse set of objects. We want to create a common approach to generating logs. We define a method toLogString() for each object type to display a label and the object's current state. If we were writing TypeScript, the interface might look like this:

      interface Loggable {
        toLogString(): string;
      }
      

      We define a function, createLogMethod(). It accepts a label, and returns a method that will log an object’s current state. It might look like so:

      function createLogMethod(label) {
        return function toLogString() {
          return `[${label}]: ${JSON.stringify(this)}`;
        }
      }
      

      We can use it like so:

      class Book {
        constructor(title, author) {
          this.title = title;
          this.author = author;
        }
      }
      
      // We can assign the method using the class prototype.
      Book.prototype.toLogString = createLogMethod('Book');
      
      // Alternatively, we can create a method property
      class Sensor {
        constructor(location, uri) {
          this.location = location;
          this.uri = uri;
        }
      
        toLogString = createLogMethod('Sensor');
      }
      

      We can then make a function, log(), that works with any Loggable object:

      /** @typedef {{ toLogString(): string }} Loggable */
      
      /** Log
       * @param {Loggable} obj An object that implements the
       *     Loggable interface
       */
      const log = (obj) => console.log(obj.toLoggableString());
      

      Since log() doesn't use the this keyword at all, it's fine to use a fat arrow function. We can use it with objects like so:

      const myBook = new Book(
        'The Hound of the Baskervilles',
        'Arthur Conan Doyle'
      );
      
      const mySensor = new Sensor(
        'Baker St',
        'http://example.com/sensors/baker-st'
      );
      
      log(myBook);
      // đŸȘ” [Book]: {"title":"The Hound of the Baskervilles","author":"Arthur Conan Doyle"}
      log(mySensor);
      // đŸȘ” [Sensor]: {"location":"Baker St","uri":"http://example.com/sensors/baker-st"}
      

      Function statements and hoisting

      There is another scenario where you might prefer function statements over arrow functions. This scenario mainly concerns the readability of our code. Perhaps we want to write our code so that the high-level code comes first. And then we follow with the implementation details later. Ordinarily, we can't use a function expression or an arrow function before it's defined. But with function declarations , we have more flexibility. For example:

      const EXCLUDED_WORDS = ['it', 'a', 'the', 'to', 'do', 'on', 'my', 'is', 'an' ];
      
      function pigLatinifyText(str) {
        // The return statement below is the main body of our
        // function. It calls other functions that haven't
        // been defined yet. The function definitions below
        // are 'hoisted' and treated as if they had been
        // written just above this comment.
        return splitIntoWords()
          .map(latinifyWord)
          .join(' ');
      
        // Usually, everything after a return statement is
        // ignored. But the function statements below still
        // work.
      
        function splitIntoWords() {
          return str.split(' ');
        }
      
        function latinifyWord(word) {
          if (EXCLUDED_WORDS.includes(word)) return word;
          const [prefix, suffix] = partition(
            isConsonant,
            word.split('')
          );
          return `${suffix.join('')}${prefix.join('')}ay`;
        }
      
        function partition(p, arr) {
          // This is not the most efficient way to write
          // partition(), but it gets the job done.
          return [takeWhile(p, arr), dropWhile(p, arr)];
        }
      }
      
      const encoded = pigLatinifyText(
        'there is nothing more deceptive than an obvious fact'
      );
      console.log(encoded);
      // đŸȘ” erethay is othingnay oremay eceptiveday anthay an obviousay actfay
      

      Putting it all together

      We've now examined some use cases where you might prefer one function syntax over another. We can use what we've learned to create a flow chart that will help us determine which function syntax to use.

      Of course, these are just my suggestions. You're free to write code any way that works. You're even free to write code in a way that doesn't work, should you so choose.

    7. 🔗 r/wiesbaden Badeseen in der NĂ€he. rss

      Hi. Gibt es in der Umgebung von Wiesbaden empfehlenswerte Badeseen oder irgendwelche RheinstrĂ€nde wo man entspannt liegen und schwimmen gehen kann. FreibĂ€der mit Schwimmbecken sind nicht so mein Fall. Danke schonmal fĂŒr eure Tipps.

      submitted by /u/Mysterious-Food-7221
      [link] [comments]

    8. 🔗 r/reverseengineering Action Camera or DIY Camera to mount on bike rss

      I have a question ke
      I want to buy an action for my bike and I want to mount it on the helmet
      But keeping view in budget and as a student, one person suggested me to buy the rear camera of a car (japanese camera)
      Mount it on the helmet
      attach a battery which provide DC 12 volts
      and diy the data wire to connect it to the mobile
      or make ot wireless
      Any suggestions ?
      I really need thou because I am tired and sick off due to current traffic violations

      submitted by /u/Master-Leek-6106
      [link] [comments]

    9. 🔗 r/reverseengineering Govee H6047 BLE control — does it require a handshake before accepting write commands? rss

      Hi everyone,
      I'm currently trying to control a Govee H6047 light using Bluetooth Low Energy (BLE) directly from Python (using the bleak library), without relying on the official Govee app.

      I can successfully connect to the device, and I’m using the correct writable characteristic UUID:
      00010203-0405-0607-0809-0a0b0c0d2b11

      I’ve reverse-engineered the protocol and I'm sending 20-byte packets formatted like this:

      • Starts with 0x33
      • Followed by a command byte (e.g., 0x05 for color)
      • Followed by the payload (e.g., RGB values)
      • Zero-padded to 19 bytes
      • Ends with a checksum byte (XOR of all previous bytes)

      However, every time I attempt to write, I get the following error:

      vbnetCopiarEditarBleakError: Could not write value [...] to characteristic ... : Unreachable
      

      The connection is successful
      The characteristic supports write and write-without-response
      Packet format and size are valid (confirmed via sniffer and other scripts)

      But it still fails to write.

      My hypothesis:

      Newer Govee models (like the H6047, post-2022) may require an initial handshake , or some sort of session activation before accepting commands — possibly:

      • A notification subscription (start_notify)
      • A write to a hidden control UUID
      • An initialization packet sent automatically by the app upon connection

      This would explain why:

      • The official app works flawlessly without internet
      • But any direct BLE command from external tools fails with “Unreachable”

      Questions:

      • Has anyone successfully controlled the H6047 directly over BLE?
      • Do you know what the app sends right after connecting?
      • Can the handshake or unlock packet be captured and replayed from Python?

      Thanks in advance!

      submitted by /u/Anexo070
      [link] [comments]

    10. 🔗 Filip Filmar VHDL IEEE Libraries and Numeric Type Conversion: A Definitive Reference rss

      I asked Gemini to teach me the VHDL type conversions. What you read below is the result. An annoying generated podcast will be available for a while. VHDL IEEE Libraries and Numeric Type Conversions: A Definitive Reference Introduction The VHSIC Hardware Description Language (VHDL) is a formal, strongly-typed language engineered for use in all phases of the creation of electronic systems, including development, verification, synthesis, and testing.1 Its dual nature, being both human-readable and machine-readable, underpins its role in communicating, maintaining, and procuring hardware designs.