1.84K subscribers
3.27K photos
130 videos
15 files
3.55K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
А помните, был такой Клаб хауз?
👍171
Пост годичной давности:
Forwarded from The After Times
Master — барская ветвь.
Slave — холопская ветвь.
Issue — донос.
Pull — арест / захват.
Push — продавить.
Stars — звезды на погонах.
Maintainer — гражданин начальник.
Contributor — кодо-обязанный
Release — амнистия.
Milestone — пятилетка.

via @shatrov_g
🔥112👍1
My programming proverbs:

Short code is nice but not required.
Ensure preconditions are met.
No hungarian notation.
Delegate allocations to caller.

Narrow interfaces are preferable.
Universal solution is not always the most efficient.
Development is not only coding but communication.
Early exits are better.
Security can't be added retroactively.
👍146
#prog #rust #моё

Как скомпилировать задницу

В ASCII-символах можно составить стилизованное изображение ягодиц:

()()

(Или, если вы предпочитаете пошире, ( )( ))

В Чат*е возник (не спрашивайте, как) вопрос, можно ли сделать этот код компилирующимся. Что ж, тут есть парочка возможностей срезать углы.

Во-первых, можно, очевидно, считать это частью синтаксиса вызова функции. Тогда можно сделать возвращающую функцию функцию, вызвать её и вызвать результат:

fn func() -> fn() { || {} }

fn f() {
func()()
}

Во-вторых, можно сделать макрос, который проглотит вообще любой синтаксис, лишь бы он разбивался на токены Rust:

macro_rules! butt { ($a:tt $b:tt ) => {}; }

butt! {
()()
}

Но это всё уловки. Если же разбирать это, как отдельное выражение, то это unit, который вызван, как функция без аргументов. В принципе, этот синтаксис можно сделать валидным, если реализовать FnOnce() для (), но у нас нет такой возможности из-за orphan rule: трейт FnOnce определён в core (платформо-независимая часть стандартной библиотеки Rust), а () вообще является примитивным типом. Так что без шансов.

ИЛИ ВСЁ-ТАКИ МОЖНО? Нам мешается core — значит, избавимся от неё! Для этого нам понадобится фича no_core — странная, толком недокументированная и, скорее всего, навечно нестабильная. Её существование может показаться странной, но в ней есть смысл: в конце-концов, core не может зависеть от себя же.

Что ж, выпишем первые строчки:

#![feature(no_core)]
#![no_std] // std нам тоже не нужно
#![no_core]

Так как FnOnce определён в core, которую мы только что собственноручно отключили, нам придётся определить этот трейт самостоятельно. Разумеется, он не является обычным трейтом. Во-первых, его реализация включает столь нужный нам синтаксис вызова — неудивительно, что он является lang item. Просто так определить lang item мы не можем, нам понадобится ещё одна фича: собственно, lang_items. Во-вторых, единственный метод call_once определён со специальным ABI "rust-call". Само его использование требует дополнительной фичи unboxed_closures (название историческое, с тех времён, когда из-за отсутствия impl Trait не было возможности вернуть замыкание иначе, как кроме боксинга). Что ж, допишем код дальше:

#![feature(lang_items, unboxed_closures)]

#[lang = "fn_once"]
trait FnOnce<Args> {
#[lang = "fn_once_output"]
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

НО! У нас тут есть обобщённые аргументы, а значит, есть и неявное ограничение Sized. Значит, этот трейт нам тоже потребуется определить:

#[lang = "sized"]
pub trait Sized {}

Теперь, когда у нас есть необходимые инструменты и мы более не связаны оковами когерентности, мы можем заставить unit вести себя, как безаргументную функцию:

impl FnOnce<()> for () {
type Output = ();
extern "rust-call" fn call_once(self, _: ()) -> () {}
}

Осталось только реализовать сидалище:

pub fn bottom() {
( )( )
}

О да, вот теперь оно компилируется. Код целиком:

#![feature(lang_items, no_core, unboxed_closures)]

#![no_std]
#![no_core]

#[lang = "sized"]
trait Sized {}

#[lang = "fn_once"]
trait FnOnce<Args: ?Sized> {
#[lang = "fn_once_output"]
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

impl FnOnce<()> for () {
type Output = ();
extern "rust-call" fn call_once(self, _: ()) -> () {}
}

pub fn bottom() {
( )( )
}

Извините, в этот раз без гиста.
8👍6🤯2
В СМЫСЛЕ УЖЕ МАЙ
#article

Imposter Syndrome (в блоге inside Rust)

This is the most fundamental philosophy of both the Rust language and the Rust project: we don't think it's sufficient to build robust systems by only including people who don't make mistakes; we think it's better to provide tooling and process to catch and prevent mistakes.
👍41
Forwarded from Empty Set of Ideas
https://elicit.org/

Крутой инструмент на базе ИИ: ищет релевантные статьи по запросу и выделяет в них ответы на заданный вопрос. Пока что бесплатно
🔥5
#prog #parsing #article

Faster general parsing through context-free memoization (pdf, thanks @zukaboo)

(thanks @grammarware, @GabrielFallen)

We present a novel parsing algorithm for all context-free languages. The algorithm features a clean mathematical formulation: parsing is expressed as a series of standard operations on regular languages and relations. Parsing complexity w.r.t. input length matches the state of the art: it is worst-case cubic, quadratic for unambiguous grammars, and linear for LR-regular grammars. What distinguishes our approach is that parsing can be implemented using only immutable, acyclic data structures. We also propose a parsing optimization technique called context-free memoization. It allows handling an overwhelming majority of input symbols using a simple stack and a lookup table, similarly to the operation of a deterministic LR(1) parser. This allows our proof-of-concept implementation to outperform the best current implementations of common generalized parsing algorithms (Earley, GLR, and GLL). Tested on a large Java source corpus, parsing is 3–5 times faster, while recognition—35 times faster.

Честно скажу, я прочитал по диагонали, но фактически алгоритм выглядит, как parsing with derivatives, но сделанный правильно.
Настроение: написать статью вместе с несколькими людьми под псевдонимом Norman Problem, чтобы на статью ссылались, как "N. Problem et al"
🔥101👎1🤩1
Без контекста
Anonymous Poll
31%
Артем
29%
Люк
20%
Вин
20%
Мариус
👎4👍2
Блог*
Без контекста
Мне вот интересно, кто из 136 проголосовавших реально понимает, о чём идёт речь?
Блог*
Без контекста
Понимаете, о чём идёт речь?
Anonymous Poll
10%
Понимаю
90%
Не понимаю
💩121
Блог*
Понимаете, о чём идёт речь?
Те, кто понимают... Напишите в личку, пожалуйста, мне обсуждать не с кем(
😁3