Smalltalk Variadic функции - PullRequest
       11

Smalltalk Variadic функции

5 голосов
/ 06 октября 2010

Имеет ли Smalltalk (особенно Squeak / Pharo) какую-либо форму функций вариации?

Я только что читал о силе создания ваших собственных контрольных характеристик в smalltalk, и хотя я большой поклонник ifTrue: ifFalse: мне было трудно придумать хороший способ реализации произвольного if, если еще , если еще, ..., операторы else, думающие, насколько полезны функции Variadic для реализации операторов case. Что-то вроде

ложный класс

ifTrue: aBlock (... elseIf: aBoolean then: aSecondBlock ...) else: aLastBlock

vArgList pairsDo: [:x :y| x ifTrue:[^ (y value)] ].
^ aLastBlock

Ответы [ 3 ]

3 голосов
/ 06 октября 2010

Подобный ключевому слову синтаксис Smalltalk для вызовов методов по сути определяет арность метода.Там нет шаблона &rest, как в Common Lisp.

Конечно, вы можете иметь метод для получения списка, например BlockClosure>>valueWithArguments:, но это вряд ли то же самое.

Вы можете изменить Compiler для поддержки вызовов метода variadic.Возможно, вызов будет просто иметь with: между каждой из переменных:

(условие) ifTrue: aBlock elseIf: aBoolean with: aSecondBlock with: anotherBoolean with: aThirdBlock

1 голос
/ 24 октября 2010

Одна вещь, которую я узнал в программировании, состоит не в том, что вам не нужны операторы case, вам не нужны операторы case.

Операторы case - это путь краздувать объект.Когда вы используете его, вы ухудшаете обслуживание.У вас будет все возможности, которые вы хотите в это время, но в тот день, когда вы захотите добавить что-то, вам придется пересмотреть неприятный код, когда вы уже не будете помнить тонкости ответственности этого объекта, поэтому вы будете раздувать егодаже больше.

В краткосрочной перспективе они выглядят дружелюбно, но заявления по делу не ваши друзья.Они будут кусать вас в долгосрочной перспективе.

Также они делают ваш код менее гибким.Например, вы не можете уверенно добавить регистр в отношении предыдущего кода.Вы вынуждены просматривать старый код, когда уже не помните его, почему он был так закодирован.

Операторы Case - враги хорошего кода.

Если у вас есть что-то, что выходит за рамки ifTrue: ifFalse: тогда правильно сделать для этого состояния.Итак, вы делаете, чтобы реализовать три класса, которые очень просты, и все они понимают какой-то глагол.

Скажите, #doTheNextThing.Поэтому, когда объект получает сообщение, которое он делегирует состоянию (в зависимости от того, какое из этих 3 (или 30, так что обратите внимание, это хорошо масштабирует сложность)), и состояние знает, как заставить исходный получатель правильно реагировать.

Это сделает ваш код легким, очевидным и легко обслуживаемым.Вы сможете забыть об этом, потому что знаете, что, когда вы снова посмотрите на это, все становится настолько очевидным, что вам не нужно думать о прошлом своего кода так же, как о будущем своего кода.

Это важно, потому что ваша память самая дорогая из имеющихся у вас, а AFAIK не подлежит обновлению.Таким образом, эта техника позволяет вам делать более мощные вещи.

Кроме того, создание 3-х классов для некоторых может показаться больше работы, но это не так.Любой noob может добавить 3 пустых класса в мгновение ока, но только правильный эксперт вспомнит, как инструкция case в старом коде была сделана так, как она была сделана.И если вы безумно оптимистичны, вам потребуется несколько минут, чтобы вспомнить, чтобы вы все знали, что делать дальше.Подумай об этом.

1 голос
/ 12 октября 2010

Вы можете использовать сообщение #caseOf:otherwise:.Ищите какого-нибудь отправителя этого сообщения для какого-то примера.

Но в любом случае, если вы хотите использовать оператор case, вы не следуете мелочному образу действий.Скажите нам, чего вы хотите достичь в своем заявлении, чтобы мы могли показать вам более понятный способ сделать это.

...