Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

24.03.2017

Google
WWW CITForum.ru
С Новым годом!
2003 г

Еще о функциональном программировании на Python

Автор: David Mertz, Ph.D., Applied Metaphysician, Gnosis Software, Inc
Перевод: Intersoft Lab

Эта статья продолжает серию статей о функциональном программирования (ФП) на Python. В ней демонстрируется несколько достаточно сложных концепций ФП. Читателю окажется полезным введение в различные подходы программного решения задач.

Что такое Python?

Python - свободно доступный, интерпретируемый язык программирования высокого уровня, разработанный Гвидо ван Россумом (Guido van Rossum). Он объединяет ясный синтаксис с мощной (но необязательно) объектно-ориентированной семантикой. Python может быть установлен на любой платформе и обеспечивает прекрасную совместимость при переходе с одной платформы на другую.

Переходим на функциональное программирование?

В предыдущей статье "Функциональное программирование на Python" были освещены основные понятия функционального программирования (ФП). В этой статье мы попытаемся немного углубиться в эту богатейшую концептуальную область. Библиотека Xoltar Toolkit Брина Келлера (Bryn Keller) окажет нам в этом неоценимую помощь. Основные возможности ФП Келлер представил в виде небольшого эффективного модуля на чистом Python. Помимо модуля functional, в Xoltar Toolkit входит модуль lazy, поддерживающий структуры, вычисляемые "только когда это необходимо". Множество функциональных языков программирования поддерживают отложенное вычисление, поэтому эти компоненты Xoltar Toolkit предоставят вам многое из того, что вы можете найти в функциональном языке наподобие Haskell.

Присвоение значений

Внимательный читатель помнит об упоминаемом мной ограничении функциональной техники, описанной в предыдущей статье. Речь шла о том, что ничто в Python не запрещает переприсваивания другого значения имени, ссылающемуся на функциональное выражение. В ФП под именами понимается всего лишь буквенное сокращение более длинных выражений, при этом подразумевается, что одно и то же выражение всегда приводит к одному и тому же результату . Если же уже определенному имени присваивается новое значение, это допущение нарушается. Предположим, мы определяем неколько сокращений для использования в нашей функциональной программе, как в следующем примере:

    #---- FP-сессия Python с переприсваиванием приводит к неприятностям ---#
    >>> car = lambda lst: lst[0]
    >>> cdr = lambda lst: lst[1:]
    >>> sum2 = lambda lst: car(lst)+car(cdr(lst))
    >>> sum2(range(10)) 1
    >>> car = lambda lst: lst[2]
    >>> sum2(range(10)) 5

К несчастью, одно и то же выражение sum2(range(10)) вычисляется к разным результатам в двух местах программы, несмотря на то, что аргументы выражении не являются изменяемыми переменными.

К счастью, модуль functional предоставляет класс Bindings (предложенный Келлеру автором), предотвращающий такое переприсваивание (по крайней мере, случайное; Python не препятствует решительному программисту намеренно нарушать правила). Хотя использование Bindings требует немного дополнительного кода, это оградит вас от случайностей. Келлер обозначает экземпляр класса Bindings как let (я полагаю, из-за зарезервированного слова let в ML-языках программирования).

Например, мы могли бы сделать следующее:

    #------- FP-сессия Python с защитой от переприсваивания -------#
    >>> from functional import *
    >>> let = Bindings()
    >>> let.car = lambda lst: lst[0]
    >>> let.car = lambda lst: lst[2]
    Traceback (innermost last):
             File "", line 1, in ?
             File "d:\tools\functional.py", line 976, in __setattr__
               raise BindingError, "Binding '%s' cannot be modified." % name
    functional.BindingError:  Binding 'car' cannot be modified.
    >>> let.car(range(10)) 0

Разумеется, реальная программа должна перехватить и обработать исключение BindingError, однако сам факт его возбуждения позволяет избежать целого класса проблем.

Помимо класса Bindings, functional содержит функцию namespace, предоставлюющую доступ к пространству имен (на самом деле, к словарю) из экземпляра класса Bindings. Это очень удобно, если вам нужно вычислить выражение в (неизменяемом) пространстве имен, определенном в Bindings. Функция eval() в Python позволяет проводить вычисление в пространстве имен. Следующий пример поясняет сказанное:

    #----- FP-сессия Python, использующая неизменяемые пространства имен -----#
    >>> let = Bindings()      # "Real world" function names
    >>> let.r10 = range(10)
    >>> let.car = lambda lst: lst[0]
    >>> let.cdr = lambda lst: lst[1:]
    >>> eval('car(r10)+car(cdr(r10))', namespace(let))
    >>> inv = Bindings()      # "Inverted list" function names
    >>> inv.r10 = let.r10
    >>> inv.car = lambda lst: lst[-1]
    >>> inv.cdr = lambda lst: lst[:-1]
    >>> eval('car(r10)+car(cdr(r10))', namespace(inv))
    17

Замыкание

В ФП существует очень интересное понятие - замыкание (closure). На самом деле, эта идея оказалась настолько заманчивой для многих разработчиков, что реализована даже в нефункциональных языках программирования, таких как Perl и Ruby. Кроме того, похоже, что в Python 2.1 неизбежно будет включен лексический контекст[1], что на 99% приблизит нас к замыканиям.

Так что же такое замыкание? Стив Маджевски (Steve Majewski) замечательно охарактеризовал это понятие в одной из посвященных Python сетевых конференций:

Объект - это совокупность данных вместе с привязанными к ним процедурами...
Замыкание - это процедура вместе с привязанноой к ней совокупностью данных.

Другими словами, замыкание есть что-то наподобие функционального доктора  Джекилла по отношению к объектно-ориентированному мистеру Хайду (или, возможно, наоборот). Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.

Давайте вернемся немного назад, чтобы понять, какую проблему решают как объекты, так и замыкания, и как эта проблема решается без них. Обычно результат, возвращаемый функцией, определяется контекстом во время ее вычисления. Самый общий - и, возможно, самый очевидный - способ определить этот контекст - это передать в функцию параметры, указывающие, какие значения должны обрабатываться. Но иногда имеется вполне очевидное различие между "фоновыми" и "приоритетными" параметрами - между тем, что делает функция в данный момент, и тем, как она сконфигурирована для выполнения многократных потенциальных вызовов.

Существует ряд способов поддержки фоновых аргументах, акцентируя внимание на приоритетных. Например, можно просто  передавать каждый необходимый аргумент в функцию при каждом ее вызове. Часто это сводится к передаче ряда значений (или структуры со множеством членов) на протяжении всей последовательности вызовов, чтобы передать данные туда, где они могут потребоваться. Это иллюстрируется простым примером:

    #--------- Python session showing cargo variable --------#
    >>> def a(n):
    ...     add7 = b(n)
    ...     return add7
    ...
    >>> def b(n):
    ...     i = 7
    ...     j = c(i,n)
    ...     return j
    ...
    >>> def c(i,n):
    ...     return i+n
    ...
    >>> a(10)     # Pass cargo value for use downstream
    17

В этом примере, параметр n в пределах функции b() нужен только для того, чтобы быть доступным для передачи в c().

Другое возможное решение - использование глобальных переменных:

    #--- Сессия Python, показывающая использование глобальной переменной ---#
    >>> N = 10
    >>> def addN(i):
    ...     global N
    ...     return i+N
    ...
    >>> addN(7)   # Добавить глобальную переменную N к аргументу
    17
    >>> N = 20
    >>> addN(6)   # Добавить глобальную переменную N к аргументу
    26

Глобальная переменная доступна в любой момент, где бы вы ни вызывали addN(), при этом вовсе не обязательно явно передавать фоновый контекст .

Несколько более "питоновская" техника - "заморозить" переменную в функции, используя для этого значение параметра по умолчанию во время определения функции:

    #-------- Сессия Python, иллюстрирующая замороженную переменную --------#
    >>> N = 10
    >>> def addN(i, n=N):
    ...     return i+n
    ...
    >>> addN(5)   # Добавить 10
    15
    >>> N = 20
    >>> addN(6)   # Добавить 10 (текущее значение N не играет роли)
    16

Замороженная нами переменная, в сущности, замыкание. Некие данные прикреплены к функции addN(). В случае полного замыкания, все данные, присутствовавшие в момент описания этой функции, были бы доступны при ее вызове. Однако в данном примере (и во многих более серьезных) можно просто обеспечить доступ к достаточному количеству данных с помощью параметров по умолчанию. Ведь переменные, которые не используются функцией addN(), не играют никакой роли при ее вычислении.

Давайте рассмотрим объектный подход на примере несколько более насущной проблемы. В это время года мысли обычно заняты интерактивными программами, используемыми для вычисления налога. Они собирают различные данные - необязательно в определенном порядке - а затем в какие-то момент используют их при вычислении. Давайте создадим упрощенный вариант такой программы:

    #----- Класс в стиле Python для вычисления налога ------#
           class TaxCalc:
               def taxdue(self):
                   return (self.income-self.deduct)*self.rate

           taxclass = TaxCalc()
           taxclass.income = 50000
           taxclass.rate = 0.30
           taxclass.deduct = 10000
           print "Pythonic OOP taxes due =", taxclass.taxdue()

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

Теперь давайте посмотрим, как можно решить эту задачу с помощью ООП с использованием передачи сообщений (это похоже на Smalltalk или Self, так же как и на некоторые объектно-ориентированные варианты xBase, которыми я пользовался):

    #------- Smalltalk-style (Python) tax calculation -------#
           class TaxCalc:
              def taxdue(self):
                  return (self.income-self.deduct)*self.rate

              def setIncome(self,income):
                  self.income = income
                  return self

              def setDeduct(self,deduct):
                  self.deduct = deduct
                  return self

              def setRate(self,rate):
           
                self.rate = rate
                  return self

          print "Smalltalk-style taxes due =", \
                TaxCalc().setIncome(50000).setRate(0.30).setDeduct(10000).taxdue()

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

Работая с Xoltar toolkit, можно создавать полные замыкания, имеющие требуемое свойство объединения данные с функцией, а также множественные замыкания, несущие в себе различные наборы данных:

    #------- Python Functional-Style tax calculations -------#
          from functional import *

          taxdue        = lambda: (income-deduct)*rate
          incomeClosure = lambda income,taxdue: closure(taxdue)
          deductClosure = lambda deduct,taxdue: closure(taxdue)
          rateClosure   = lambda rate,taxdue: closure(taxdue)

          taxFP = taxdue
          taxFP = incomeClosure(50000,taxFP)
          taxFP = rateClosure(0.30,taxFP)
          taxFP = deductClosure(10000,taxFP)
          print "Functional taxes due =",taxFP()

          print "Lisp-style taxes due =", \
                incomeClosure(50000,
                    rateClosure(0.30,
                        deductClosure(10000, taxdue)))()

Каждая описанная нами функция замыкания берет любые значения, определенные в ее области видимости, и привязывает эти величины к глобальной области видимости функционального объекта. Однако то, что кажется глобальной областью данной функции, необязательно совпадает как с "настоящей" глобальной областью действия модуля, так и с глобальной областью другого замыкания. Замыкание просто "несет данные с собой".

В нашем примере, чтобы поместить определенные значения в область действия замыкания, мы используем несколько частных функций (income, deduct, rate). Было бы достаточно просто изменить дизайн так, чтобы было можно присваивать произвольные значения. Кроме того, ради развлечения, мы используем в этом примере два слегка различных функциональных стиля. Первый последовательно привязывает дополнительные значения к области замыкания; сделав taxFP изменяемой, мы позволяем строкам добавить в замыкание появляться в любом порядке. Однако, если бы мы использовали неизменяемые имена наподобие tax_with_Income, нам пришлось бы  расположить связывания в определенном порядке и передавать более ранние последующим. В любом случае, как только все необходимое привязано к замыканию, мы можем вызывать выращенную функцию.

Второй стиль, на мой взгляд, несколько похож на Lisp (исключительно из-за присутствия круглых скобок). Помимо эстетики, во втором стиле присутствуют два интересных момента.

Во-первых, полностью отсутствует привязывание имен. Второй стиль - одиночное выражение без использования директив[2]. (см. предыдущую статье, где объясняется, почему это играет роль).

Другая интересная деталь Lisp-стиля в том, насколько сильно его использование замыканий напоминает методы передачи сообщений a la Smalltalk, о которых говорилось выше. В обоих случаях значения накопливаются до вызова функции/метода taxdue() (оба в этих упрощенных версиях возбуждают исключения, если требуемые данные недоступны). Smalltalk-стиль на каждом шаге передает объект, в то время как Lisp-стиль - продолжение (continuation). Но если смотреть в корень, то функциональное и объектно-ориентированное программирование приводят почти к одному и тому же.

Хвостовая рекурсия

В этой статье мы еще немного вгрызлись в гранит функционального программирования. То, что осталось, меньше (и, возможно, проще) того, что сделано (название этого раздела - небольшая шутка; к сожалению, ее суть пока не разъяснена). Отличный способ дальнейшего освоения множества концепций ФП - просмотреть исходники модуля functional. Модуль прекрасно откомментирован и содержит примеры для большинства функций/классов. В этой статье не были рассмотрены некоторые мета-функции, упрощающие комбинацию и взаимодействие других функций. Они определенно стоят изучения для программиста на Python, стремящегося продолжить изучение подходов функционального программирования.

Ресурсы

Библиотека Xoltar toolkit, написанная Брином Келлером и включающая модуль functional, значительно расширяет возможности ФП на Python. Поскольку модуль functional написан на чистом Python, все, что он делает так или иначе уже возможно в Python. Но Келлер создал очень удачный комплект расширений, предоставлющий большую мощность при компактности определения. Библиотеку можно найти по адресу:

http://sourceforge.net/projects/xoltar-toolkit

Питера Норвиг (Peter Norvig) написал очень интересную статью: Python для программистов на Lisp (Python for Lisp Programmers). И хотя ее фокус прямо противоположен моей статье, в его работе проводится очень основательное сравнение Python и Lisp:

http://www.norvig.com/python-lisp.html

Если вы только начали изучать функциональное программирование, вы сможете найти ответы на многие вопросы по адресу:

http://www.cs.nott.ac.uk/~gmh//faq.html#functional-languages

Автор находит, что гораздо легче понять суть функционального программирования, используя язык Haskell, а не Lisp/Scheme (несмотря на то, что последний чаще используется, хотя бы в Emacs). Кроме того, программистам на Python будет много проще жить без такого количества круглых скобок и префиксной (польской) записи:

http://www.haskell.org/

Прекрасная вводная книга:

Haskell: The Craft of Functional Programming (2nd Edition)
qSimon Thompson, Addison-Wesley (1999).

Об авторе

(Фотография автора: http://gnosis.cx/cgi-bin/img_dqm.cgi)

Поскольку постижение без интуиции бесплодно, а интуиция без постижения слепа, Дэйвид Мертц хочет литой бюст Джона Мильтона в свой офис. Запланируйте подарить ему на день рождения. Дэйвид доступен по адресу: mertz@gnosis.cx, а жизнь его описана на http://gnosis.cx/publish/. Присылайте свои замечания и предложения касательно этой, прошлых или будущих статей.



[1] В Python 2.1 лексический контекст имен (статически вложенный контекст) реализован как опциональное свойство (from __future__ import nested_scopes). В Python 2.2 это свойство стало обязательным. (Прим. перев.)

[2] Обычно слово "statement" переводится как "оператор", но это неудачно тем, что "оператор" означает также и "оператор в выражении" (например, арифметический), а не только "императивное утверждение". Более того, в функциональных языках "оператор" означает только "оператор в выражении"! Поэтому здесь мы будем пользоваться словом "директива" для обозначения того, что в англоязычной компьютерной литературе обозначается словом statement. (Прим. перев.)



Оригинальный текст статьи можно посмотреть здесь:
More Functional Programming in Python

Размещение рекламы — тел. +7 495 4119920, ICQ 232284597

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

24 декабря

CITKIT.ru:

  • Новогодние поздравления
  • Сергей Кузнецов. Цикл Операционные системы: Ностальгия по будущему:

  • Алексей Федорчук. OpenSolaris 2008.11 Release

  • Сергей Голубев:

  • Евгений Чайкин aka StraNNik (Блогометки):

    17 декабря

  • С.Д.Кузнецов. Базы данных. Вводный курс

    10 декабря

    CITKIT.ru:

  • OpenSolaris 2008.11 Release

  • Альтернативные ОС: две грустные истории (С.Кузнецов)
  • Nokia N810 — доведение до ума
  • CitCity:

  • Платформа 2009: заоблачные перспективы Microsoft

    4 декабря

  • Лекция С.Д.Кузнецова Понятие модели данных. Обзор разновидностей моделей данных

    CITKIT.ru:

  • OpenSolaris 2008.11 Release. Первые впечатления

  • Linux vs FreeBSD: продолжим "Священные войны"?

  • Nokia N810 as is

  • Индульгенция для FOSS

  • Друзья СПО'2008

    26 ноября

  • Нечеткое сравнение коллекций: семантический и алгоритмический аспекты

    CitCity:

    CITKIT.ru:

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • 19 ноября

  • Проблемы экономики производства крупных программных продуктов

  • Язык модификации данных формата XML функциональными методами

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Заметки к книге:

  • FreeBSD: монтирование сменных устройств и механизм HAL
  • Текстовый редактор ee

    12 ноября

  • Правило пяти минут двадцать лет спустя, и как флэш-память изменяет правила (Гоц Грейф, перевод: Сергей Кузнецов)

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:
  • OSS в России: взгляд правоведа (В.Житомирский)

  • Новая статья из цикла С.Голубева "Железный марш":

    29 октября

  • О некоторых задачах обратной инженерии

  • Веб-сервисы и Ruby

  • Тестирование web-приложений с помощью Ruby

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

  • PuppyRus Linux - беседа с разработчиком (С.Голубев)

  • Сергей Кузнецов. Заметка не про Linux

    22 октября

  • Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки

    CITKIT.ru:

  • Сергей Кузнецов. Почему я равнодушен к Linux

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • Что надо иметь
    3. Базовые познания

    CitCity:

  • Управление IT-инфраструктурой на основе продуктов Microsoft

    15 октября

  • Методы бикластеризации для анализа интернет-данных

    CitCity:

  • Разъемы на ноутбуках: что они дают и зачем их так много?
  • AMD Puma и Intel Centrino 2: кто лучше?

    CITKIT.ru:

  • Новый цикл статей С.Голубева
    Железный марш:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    8 октября

  • Автоматизация тестирования web-приложений, основанных на скриптовых языках
  • Опыт применения технологии Azov для тестирования библиотеки Qt3

    Обзоры журнала Computer:

  • SOA с гарантией качества
  • Пикоджоуль ватт бережет
  • ICT и всемирное развитие

    CitCity:

  • Пиррова победа корпорации Microsoft

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Статья из архива:

  • Я живу в FreeBSD (Вадим Колонцов)

    Новые Блогометки:

  • Перекройка шаблона Blogger или N шагов к настоящему
  • Blogger. Comment style
  • Screenie или глянцевый снимок экрана

    2 октября

    CITKIT.ru:

  • Сага о FreeBSD (А. Федорчук)

    Zenwalk: пакет недели

  • Банинг — интеллектуальное развлечение (С.Голубев)

    CitCity:

    25 сентября

  • Клермонтский отчет об исследованиях в области баз данных

    CITKIT.ru:

  • Пользователям просьба не беспокоиться... (В.Попов)

  • Снова про ZFS: диск хорошо, а два лучше
  • Командная оболочка tcsh (А.Федорчук)

    Zenwalk: пакет недели

    17 сентября

  • T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов
  • Технология Azov автоматизации массового создания тестов работоспособности

    CITKIT.ru:

  • FreeBSD: ZFS vs UFS, и обе-две — против всех (А.Федорчук)

    Zenwalk: пакет недели

  • Дачнет — практика без теории (С.Голубев)

    10 сентября

  • За чем следить и чем управлять при работе приложений с Oracle
  • Планировщик заданий в Oracle
    (В.Пржиялковский)

    CITKIT.ru:

  • Microsoft: ответный "боян" (С.Голубев)

  • Причуды симбиоза, или снова "сделай сам" (В.Попов)

  • Файловые системы современного Linux'а: последнее тестирование
  • Zsh. Введение и обзор возможностей
    (А.Федорчук)

    Описания пакетов Zenwalk: Zsh, Thunar, Thunar-bulk-rename, Xfce4-places-plugin, Xfce4-fsguard-plugin

    Блогометки:

  • Google Chrome
  • Лончер для ASUS Eee PC 701

    3 сентября

    CITKIT.ru:

  • Заметки о ядре (А.Федорчук):

    Добавлены описания пакетов Zenwalk: Galculator, Screenshot, Gnumeric, Pidgin

    В дискуссинном клубе:

  • И еще о Википедии и Google Knol

  • Лекция для начинающего линуксоида (С.Голубев)

    26 августа

  • Транзакционная память (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Открыт новый проект Zenwalk: пакет недели

  • Статья Текстовые процессоры и их быстродействие: конец еще одной легенды?

    21 августа

    CITKIT.ru:

  • Почему школам следует использовать только свободные программы (Ричард Столлман)
  • Беседа Сергея Голубева с учителем В.В.Михайловым

  • Википедия или Гуглезнание? Приглашение к обсуждению (Алексей Федорчук)
  • Народная энциклопедия от Google (StraNNik)

  • Обзор Mandriva 2009.0 Beta 1 Thornicrofti
  • Новичок в Линукс: Оптимизируем Mandriva 2008.1

  • Книга Zenwalk. Приобщение к Linux:

    13 августа

    CitCity:

  • Мирный Atom на службе человеку. Обзор платы Intel D945GCLF с интегрированным процессором
  • Обзор процессоров Intel Atom 230 на ядре Diamondville

  • iPhone - год спустя. Скоро и в России?

    CITKIT.ru:

  • Интермедия 3.4. GRUB: установка и настройка (из книги Zenwalk. Приобщение к Linux)

    6 августа

  • СУБД с хранением данных по столбцами и по строкам: насколько они отличаются в действительности? (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Интермедия 2.2. Что неплохо знать для начала (из книги Zenwalk. Приобщение к Linux)

  • И снова про шрифты в Иксах (А.Федорчук)

  • 20 самых быстрых и простых оконных менеджеров для Linux

  • Дело о трех миллиардах (С.Голубев)

    30 июля

  • OLTP в Зазеркалье (Пересказ: С. Кузнецов)

    CitCity:

  • Будущее BI в облаках?
  • Тиражные приложения и заказная разработка. Преимущества для заказчика
  • Дискуссия со сторонниками заказной разработки

    CITKIT.ru:

  • Новые главы книги Zenwalk. Приобщение к Linux:
  • Глава 8. Пакеты: средства установки, системы управления, системы построения
  • Глава 9. Zenwalk: репозитории, пакеты, методы установки

    23 июля

    CITKIT.ru:

  • Все против всех. 64 vs 32, Intel vs AMD, tmpfs vs ext3
  • Две головы от Intel

  • Zenwalk: обзор штатных приложений (глава из книги "Zenwalk. Приобщение к Linux")

  • Нормально, Григорий...

    16 июля

    Обзоры журнала Computer:

  • Перспективы и проблемы программной инженерии в XXI веке
  • Большие хлопоты с большими объемами данных
  • Перспективы наноэлектроники

    CITKIT.ru:

  • Интермедия о лицензиях (А.Федорчук. "Zenwalk. Приобщение к Linux")

  • Есть ли будущее у KDE?

  • Linux в школе: альтернативный вариант в задачах

  • Шифр (приключения агента Никодима)

    10 июля

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия вступительная. Linux или GNU/Linux? Как вас теперь называть?
  • Глава 5. Среда Xfce
  • Глава 6. Xfce: приложения и плагины

  • ZUR (Zenwalk User Repository) FAQ

    2 июля

  • Персистентность данных в объектно-ориентированных приложениях (С. Кузнецов)

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия 1.2. Дорога к Zenwalk'у. Период бури и натиска
  • Интермедия 3.3. Немного о Linux'е и "железе"
  • Глава 4. Настройка: инструментами и руками
  • Интермедия 4.1. Zenpanel и конфиги: поиски корреляции

  • Интервью с Жан-Филиппом Гийоменом, создателем дистрибутива Zenwalk

  • Linux в школе: первые итоги (С. Голубев)

    25 июня

    CITKIT.ru:

  • Zenwalk. Приобщение к Linux (А. Федорчук)

  • Логика и риторика (С.Голубев)

  • Технология Tru64 AdvFS

  • Ханс Райзер предлагает отвести полицейских к телу Нины

    18 июня

  • Проекты по управлению данными в Google (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • ОС и поддержка "железа": мифы и реальность (А. Федорчук)

  • Linux в школе: другие дистрибутивы

  • Пинок (С. Голубев)

    4 июня

  • Ландшафт области управления данными: аналитический обзор (С. Кузнецов)

    CITKIT.ru:

  • Linux в школе: слово заинтересованным лицам

  • SlackBuild: пакеты своими руками

  • Linux от компании Novell. Установка и обзор openSUSE Linux

    Все публикации >>>




  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы — тел. +7 495 4119920, ICQ 232284597 Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2007 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...