LINUX.ORG.RU
ФорумTalks

Современный BASIC


0

1
Sub Halve (ByRef i As Integer)
    i /= 2
End Sub

Sub Triple (ByRef i As Integer)
    i *= 3
End Sub

Type operation As Sub (ByRef As Integer)

' an array of procedure pointers, NULL indicates the
' end of the array
Dim operations(20) As operation = _
{ @Halve, @Triple, 0 }

Dim i As Integer = 280

' apply all of the operations to a variable by iterating through the array
' with a pointer to procedure pointer
Dim op As operation Ptr = @operations(0)
While (0 <> *op)
    ' call the procedure that is pointed to, note the extra parenthesis
    (*op)(i)
    op += 1
Wend

Print "Value of 'i' after all operations performed: " & i

Кто первым догадается, что этот код делает? (взято из документации к FreeBASIC). Сторонникам C такая галиматья должна быть как бальзам на грудь, хотя работа с указателями на языке Intel Assembler'а, например, выглядит куда логичнее и понятнее, поскольку обходится минимумом мозолящих глаза сущностей.
Я это к тому веду, что современный BASIC всё также многословен, но по степени замороченности наступает на пятки языку C. На мой взгляд, всё же основным недостатком BASIC, из-за которого им мало кто пользуется в Linux и вообще в nix'ах - это отсутствие стандартизации. Но если считать, что, например, Java, PHP и Perl - это разновидности языка C (а так оно вообще говоря и есть, если посмотреть на их синтаксис), то BASIC с его немногочисленными живыми разновидностями (а по сути только с тремя: FreeBASIC, Gambas и Mono BASIC aka VB.Net) уже не будет казаться таким уж многоголовым чудищем. Кстати, весьма интересно, что Microsoft BASIC PDS 7.1, вышедший что-то в 89-м году или 90-м, был вообще одним из первых универсальных ЯП, отлично заточенных под работу с базами данных....

P.S А вообще программистам следовало бы думать о качестве кода, а не о том, какие инструменты правильные, а какие нет. А то получается как в басне Крылова: «а вы, друзья, как ни садитесь, всё в музыканты не годитесь».

★★★★★

>На мой взгляд, всё же основным недостатком BASIC, из-за которого им мало кто пользуется в Linux и вообще в nix'ах - это

то, что он не питон/руби/etc.

Deleted
()

Массив из функций от трех параметров, вызывается каждая из них с параметром равным индексу функции в массиве?

stevejobs ★★★★☆
()

А вообще программистам следовало бы думать о качестве кода, а не о том, какие инструменты правильные, а какие нет.

Программисты об этом и думают. Холиварят школьники и безработные.

schizoid ★★★
()

Эм. Ну, вроде как, это должно вывести «Value of 'i' after all operations perfromed: 420». Я прав или я лев?

tiandrey ★★★★★
()
Ответ на: комментарий от visual

ого 420

пока операция не нуль пополам умножнатри выведи.

Хэппи энд

Это какой-то диалект ЛОГО?

schizoid ★★★
()
Ответ на: комментарий от tiandrey

Прав-то прав, но что значит в данном случае op+=1? op судя по объявлению - это не индекс массива, это сам элемент массива. *op - разыменование ссылки, каковой является элемент массива. Ну ok, а если мы единицу к op'у прибавляем - это же... просто тц какой-то...

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Меня кстати сегодня просто поразило в книжке по программированию на C под Linux определение вида:
[code]
one_unknown_shit yet_another_strange_hell;
[/code]
Смутно догадываюсь, что это так определяется принадлежность переменной one_unknown_shit пользовательскому типу данных (записи) yet_another_strange_hell, но выглядят такие определения как некий поток сознания, понятный только разработчикам на C.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от schizoid

То есть вроде как указатель таким образом двигается по списку?
Ну в принципе если фигурные скобки объявляют список, то наверное... Но обычно для этого всё-таки не арифметические же операции используются (какая-нибудь там функция next() или что-то в этом роде).

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Но обычно для этого всё-таки не арифметические же операции используются (какая-нибудь там функция next() или что-то в этом роде).

Да, в Ъ-ООП типа Java. А в C и C++ это в порядке вещей.

schizoid ★★★
()
Ответ на: комментарий от schizoid

mov ebx, DWORD PTR [ebx][4] в данном случае решает :)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

op судя по объявлению - это не индекс массива, это сам элемент массива.

Это не элемент массива, это указатель на элемент массива. Поэтому op+1 будет указателем на следующий элемент.

tiandrey ★★★★★
()
Ответ на: комментарий от tiandrey

С точки зрения архитектуры процессора непонятно, что такая штука может означать. Единственное разумное на мой взгляд объяснение - это то, что op -это всё-таки не более, чем индекс элемента массива. Ведь он же безо всякой магии и правда увеличивается на единицу - и этом при том, что размер смещения в сегменте равен 32 битам (вроде бы 64-х битного FreeBASIC'а нет).

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

А при чём здесь вообще архитектура процессора? Васик же интерпретируется, ну или даже пусть компилируется - в любом случае, на сколько изменять указатель, решает интерпретатор/компилятор.

tiandrey ★★★★★
()
Ответ на: комментарий от DRVTiny

one_unknown_shit yet_another_strange_hell;

one_unknown_shit = тип переменной
yet_another_strange_hell = название переменной.

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

Догадка правильная, предположение неправильное. Сочетание «тип_переменной имя_переменной» встречается почти во всех языках со строгой(либо статической) типизацией при объявлении переменных. Например, C/C#/C++/D, Java, Pascal.

Slavaz ★★★★★
()
Ответ на: комментарий от DRVTiny
$ cat test.c 
#include<stdio.h>
int main(){
    int *a=12340000;
    printf("%Ld\n", a);
    a++;
    printf("%Ld\n", a);
    return 0;
}
$ ./test 
12340000
12340004

Точно так же, увеличивали на единицу, а реальное значение увеличилось на четыре. Мистика?

tiandrey ★★★★★
()
Ответ на: комментарий от tiandrey

Точно так же, увеличивали на единицу, а реальное значение увеличилось на четыре. Мистика?

OMG

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Единственное разумное на мой взгляд объяснение - это то, что op -это всё-таки не более, чем индекс элемента массива.

Это всё-таки указатель. Прирост на единицу означает на самом деле прирост на величину указателя. Говоря Сишным языком:

void *op = 0;
printf(«%p\n»); // 0
op++;
printf(«%p\n»); // 4(x86) или 8(x86_64)

Можно ещё попробовать посмотреть на такой указатель как на предок паттерна программирования Iterator(только без контроля границ; хотя как с этим в Бейсике я не знаю).

Slavaz ★★★★★
()
Ответ на: комментарий от DRVTiny

Во, но это фигня на самом деле, если бы a был long long int *, то значение увеличилось бы не на четыре, а на ВОСЕМЬ!!!

tiandrey ★★★★★
()
Ответ на: комментарий от Slavaz

В Pascal если меня склероз не подводит, объявление переменной выглядит как:
[code]
var
a: integer;
b: float;
f: boolean;
end;
[/code]
То есть могу ошибаться, но я только в C-подобных языках и то далеко не во всех встречал такое сумбурное определение из «двух_незнакомых_слов через_пробел», которое словно индусами придумано, у которых основная задача - побыстрее выдать как можно больше строк кода, так что им уже не до того, чтобы код был читабельным: плачут дома детки ведь... :)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от Slavaz

void *op

А вот тут-то и выйдет фейл, так как компилятор не знает размер элемента, на который указатель указывает. И получится 0 и 1, а не 4 и не 8.

tiandrey ★★★★★
()
Ответ на: комментарий от DRVTiny

Тут уж как бог на душу положит разработчикам языка - либо сначала тип языка, потом имена переменных, либо сначала переменные, потом тип. В си-подобных - сначала тип; pascal, basic, sql емнип - тип в конце.

tiandrey ★★★★★
()
Ответ на: комментарий от DRVTiny

В Pascal если меня склероз не подводит, объявление переменной выглядит как:

Да, в паскале порядок обратный. Я имел ввиду, что пара «тип имя» (или «имя тип») присущи всем типизированным языкам и вызывают недоумение только у адептов динамических или бестиповых языков :)

То есть могу ошибаться, но я только в C-подобных языках и то далеко не во всех встречал такое сумбурное определение из «двух_незнакомых_слов через_пробел», которое словно индусами придумано

Всего лишь дело привычки или профессионализма. Меня, например, динамическая типизация в штопор вгоняет, но при необходимости вполне на перле, питоне или пхп код наклепаю без проблем. Однако предпочтение отдаю строгой типизации, и «тип имя» читаю влёт и почти интуитивно.

Slavaz ★★★★★
()
Ответ на: комментарий от tiandrey

А вот тут-то и выйдет фейл, так как компилятор не знает размер элемента, на который указатель указывает. И получится 0 и 1, а не 4 и не 8.

нет, ошибки не будет. Потому что прирост будет на размер, необходимый для хранения любого указателя; то есть, на sizeof(void *). А он на ix86 равен 4, а на x86_64 равен 8-ми.

Slavaz ★★★★★
()
Ответ на: комментарий от tiandrey

Вы не совсем поняли, речь идёт не о порядке тип-переменная, а о том, что в том же FreeBASIC определение переменной может быть:
[code]
dim someK as double
dim as integer Index
dim auto1 as recAutoProperties
[/code]

но уж никак не просто
[code]
recAutoProperties auto1;
[/code]
для нормальной читаемости кода нужны ключевые слова, к которым «липнет» взгляд при чтении кода. А когда это просто (void *p)&sin - весь код выглядит одной большой помойкой.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

А, прошу пардона, тред не читаю, сразу отвечаю.

P.S. Use предпросмотр, Luke!

tiandrey ★★★★★
()
Ответ на: комментарий от Slavaz

Ну в этом случае логично, это будет указатель на указатель, размер которого известен.

tiandrey ★★★★★
()
Ответ на: комментарий от Slavaz

См. выше. Я тоже больше люблю языки со строгой типизацией, обжёгся уже на том же VisualBASIC и типе Variant.
Меня просто смущает стиль, в котором пишется код на C: получается, что листинг на ассемблере и то гораздо понятнее, он хотя бы абсолютно прямолинеен и там нет 100500 лишних сущностей вместо просто «адрес памяти» (указатель) и «значение по адресу» (переменная).

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от Rastafarra

Ну, я имею в виду всякие там *, **, & и сколько их ещё там. Зачем это нужно - неясно. Достаточно было просто добавить операцию ptr(obj) - получить адрес объекта в памяти.
Ведь, например, **a что значит? Это указатель на указатель. А выглядит как просто два умножения перед а. Почему нельзя было сделать какую-то более многословную, но зато удобоваримую см т.з. восприятия человеком конструкцию?
Я за то и люблю старые языки типа FORTRAN и BASIC, что они хотя бы для интерфейса между человеком и компьютером создавались, а не для взаимодействия биополуробота и компьютера.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

листинг на ассемблере и то гораздо понятнее, он хотя бы абсолютно прямолинеен и там нет 100500 лишних сущностей вместо просто «адрес памяти» (указатель) и «значение по адресу» (переменная).

Да как бы и на Си особо много сущностей нет: всё тот же указатель и значение по адресу. Можно получить указатель на любую Сишную переменную, можно по указателю присвоить куску памяти любое значение.

Разница с ассемблером в приращении указателей, компилятор берёт на себя нагрузку по вычислению значения указателя на следующий/предыдущий элемент массива. Можно таким образом «шагать» через массивы структур, объединений или любых других сложных данных всего лишь объявив указатель(с таким же типом, как и эти данные) и потом приращивая/уменьшая этот указатель на 1 или на любое другое внятное число, а не на sizeof(type)*index.

Slavaz ★★★★★
()
Ответ на: комментарий от DRVTiny

выглядит как просто два умножения перед а

некоторое время назад ты не знал сколько будет 2х2 (да и запись была странной). тебя это не смущает?

Rastafarra ★★★★
()
Ответ на: комментарий от Rastafarra

Посмотрите внимательно на это определение:

Sub Triple (ByRef i As Integer)
- это классический пример гуманистического подхода, когда считается, что компьютер должен «понимать» человеческий язык в той же мере, что и человек - компьютерный. Ассемблер подразумевает общение с компьютером на его языке (хотя макросы довольно далеко уводят от этой концепции, но это и не относится напрямую к ассемблеру).
А вот Си - это язык полуроботов, которые хотят что-то сказать на языке компьютера, но не могут это сделать в развёрнутой форме ассемблера, потому что страшно спешат выполнить свой биоплан по производству ПО.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Ну, я имею в виду всякие там *, **, & и сколько их ещё там.

http://habrahabr.ru/blogs/cpp/116255/

Зачем это нужно - неясно. Достаточно было просто добавить операцию ptr(obj) - получить адрес объекта в памяти.

Гм.. ну давайте попробуем записать из примера по ссылке
char *(*(**foo[][8])())[];

в виде «ptr()» obj:
char ptr((ptr((ptr(ptr(foo))[][8]))()))[];

Яснее стало? :)

Slavaz ★★★★★
()
Ответ на: комментарий от DRVTiny

Хотя, если честно, я сам пишу на BASH примерно такое:

{ [[ ${a%-*} =~ ^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z])?$ ]] && echo 'OK'; } }} echo 'FAIL'
Так что мой код чтобы читабельным назвать - нужно выпить очень много и быть в хорошем расположении духа.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Си - это язык полуроботов, которые хотят что-то сказать на языке компьютера

это ты еще J видимо не видел.

Rastafarra ★★★★
()
Ответ на: комментарий от Slavaz

На мой взгляд, нужно просто избегать такого уродства в коде. То есть если это этап отладки и нужно как можно быстрее сделать что-то работающее - тогда можно и так, но в итоге всё-таки код должен быть «прозрачным» с точки зрения восприятия.
То есть я хочу сказать, что затруднения при чтении подобных приведённому в статье определений - это НЕ проблема читающих, это проблема пишущих. И если пишущие смогут объяснить, почему они пользуются подобными конструкциями в коде и убедительно докажут, что иначе было ну никак нельзя (хотя сложнейшие нечёткого поиска в подстроки в строке, в т.ч. с эвристикой, как-то умудряются обходиться даже без указателей на указатели) - тогда им нужно выдать Нобелевскую премию и отпустить с миром. В противном же случае имя им - говнопрограммеры ;)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

нужно просто избегать такого уродства в коде.

я пропустил... уродство в коде --- это такой код, который лично тебе кажется непонятным (в силу незнания языка), или что?

я полагаю французкий язык вообще сродни филькиной грамоте и не нужен?

Rastafarra ★★★★
()
Ответ на: комментарий от DRVTiny

На мой взгляд, нужно просто избегать такого уродства в коде.

Всё верно. Код не должен быть излишне сложным и ориентированным только лишь на высокий профессионализм читающих этот код (если, конечно, это не код поделки, которой пользуется только автор).
Именно поэтому в Си есть user-defined типы, которыми можно упростить восприятие типов переменных, заодно осмысленно назвать этот новый тип.

Slavaz ★★★★★
()
Ответ на: комментарий от Rastafarra

уродство в коде --- это такой код, который лично тебе кажется непонятным (в силу незнания языка), или что?

В чём-то он прав. Излишне сложный для понимания код (который профессионалами читается легко и влёт) может затруднить сопровождение или разработку кода менее квалифицированными коллегами.
Конечно же, можно специально писать такой код, чтобы отсечь желающих помочь(если речь про СПО) по уровню квалификации.

Slavaz ★★★★★
()

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

nanonymous
()
Ответ на: комментарий от Slavaz

Излишне сложный для понимания код

излишне сложный --- может быть.

однако мы про фразу «Смутно догадываюсь, что это так определяется принадлежность переменной one_unknown_shit пользовательскому типу данных (записи) yet_another_strange_hell», которая доставила. дальше остапа понесло.

Rastafarra ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.